1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MySQLにおけるint型IDの限界とクラッシュ回避のための対策

Posted at

問題発生

IDをDBに保持しているが、IDがintを超えた値を持つアプリが発生し、オーバーフローでクラッシュした。

問題の原因

  • DB(データベース)では、MySQLを使用
  • MySQLでは、データに「文字列」「整数」などの"型"を設定し保存することで、DBの効率性と品質を向上
  • 問題が発生したのは「int」型で、これは整数型の一種であり、整数値を4バイト(32ビット)で保存する
  • 4バイト(32ビット)で保存している都合上、最大値は2,147,483,647までしか保存できない
  • アプリのIDが2,147,483,647を超えたため、オーバーフローエラーが発生し、クラッシュが発生

対応策

IDを保存するデータ型を「int」から「bigint」に変更する。
「bigint」は8バイト(64ビット)で整数を保存し、最大値が9,223,372,036,854,775,807まで拡張される。
これにより、オーバーフローの問題が発生しなくなる。ただし、ストレージ容量が増加する。

MySQLの整数型について

  • TINYINT
    • 符号付き: -128から127まで
    • 符号なし: 0から255まで
    • 1バイト(8ビット)を使用
  • SMALLINT
    • 符号付き: -32,768から32,767まで
    • 符号なし: 0から65,535まで
    • 2バイト(16ビット)を使用
  • MEDIUMINT
    • 符号付き: -8,388,608から8,388,607まで
    • 符号なし: 0から16,777,215まで
    • 3バイト(24ビット)を使用
  • INT
    • 符号付き: -2,147,483,648から2,147,483,647まで
    • 符号なし: 0から4,294,967,295まで
    • 4バイト(32ビット)を使用
  • BIGINT
    • 符号付き: -9,223,372,036,854,775,808から9,223,372,036,854,775,807まで
    • 符号なし: 0から18,446,744,073,709,551,615まで
    • 8バイト(64ビット)を使用

"INT"の最大値が2,147,483,647である理由

  • INT型の最大値

    • 4バイト(32ビット)の整数を格納できる
    • 32ビットを使って、符号付き整数(正数と負数の両方を含む)を表現する
    • 最初の1ビット(最上位ビット)は符号ビットとして使われ、残りの31ビットで数値を表現する

    符号付き整数の場合

    • 最上位ビットが0の場合は正の数を、1の場合は負の数を示す
    • 残りの31ビットで表現できる整数の最大値は、2の31乗から1を引いた値
    • 2^31 - 1 = 2,147,483,648 - 1 = 2,147,483,647

  したがって、INT型の最大値は2,147,483,647となります。
  
  同様に、負の数の最小値は、最上位ビットが1で、残りのビットがすべて0です。
  これは以下のように計算できます。

  -2^31 = -2,147,483,648
  よってINT型の範囲は-2,147,483,648から2,147,483,647となる

  ※整数 2,147,483,647 を32ビット符号付き整数として表現するには、2進数(バイナリ)で次のようになる
   →01111111 11111111 11111111 11111111
  ※整数 -2,147,483,647 を32ビット符号付き整数として表現するには、2進数(バイナリ)で次のようになる
   →11111111 11111111 11111111 11111111

デフォルトでBIGINTで記録しない理由

  • データベースで全ての整数型をデフォルトでBIGINT型にすると、必要以上に大きなストレージ容量やリソースを消費することになる

    • 特に大規模なデータベースや高いパフォーマンスが求められるシステムでは問題となることが考えられる
    • 1つデータを保存するのに、INTと比較して2倍のデータ量が消費される
  • 例)整数 2,147,483,647 を32ビットと64ビットで表示した場合

    • 32ビット符号付き整数: 01111111 11111111 11111111 11111111
    • 64ビット符号付き整数: 00000000 00000000 00000000 00000000 01111111 11111111 11111111 11111111
  • 例)1から2,147,483,647までのIDを保存する場合

    • 32ビットで保存する場合: 2,147,483,647(個) x 4(バイト) = 8,589,934,588バイト
    • 64ビットで保存する場合: 2,147,483,647(個) x 8(バイト) = 17,179,869,176バイト
  • リソース消費量の違い

    • 64ビットで保存した場合のストレージ容量は、32ビットで保存した場合のストレージ容量の2倍になる
    • 17,179,869,176(バイト) - 8,589,934,588(バイト) = 8,589,934,588バイト
    • つまり、1から2,147,483,647までのIDを64ビットで保存する場合、32ビットで保存する場合に比べて、約8.59GB(8,589,934,588バイト)の追加ストレージが必要になる

このため、データベースのストレージ容量やリソースは限られており、ストレージとリソースの効率性を良くするため、多くのアプリケーションでは、INTを使用することが多いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?