web-dev-qa-db-ja.com

整数列のauto_incrementがデータベースのmax_valueに達するとどうなりますか?

データベースアプリケーションを実装しています。JavaDBとMySQLの両方をデータベースとして使用します。型に整数を持つテーブルにID列があり、値にデータベースのauto_increment-functionを使用しています。

しかし、20億(または40)を超える投稿があり、整数では不十分な場合はどうなりますか?整数がオーバーフローして続行しますか、または処理できる例外がスローされますか?

はい、データ型としてlongに変更できますが、必要な場合はどのように確認すればよいですか? ID列のデータ型としてlongを使用すると、last_inserted_id()関数の取得に問題があると思います。

63
Jonas

MySQLドキュメントの §3.6.9。 "AUTO_INCREMENTの使用" からのJim Martinのコメント:

質問がある場合に備えて、AUTO_INCREMENTフィールドは/ DOES NOT WRAP /です。フィールドサイズの制限に達すると、INSERTはエラーを生成します。 (ジェレミー・コールによる)

MySQL 5.1.45を使用した簡単なテストでは、次のエラーが発生します。

エラー1467(HY000):ストレージエンジンからの自動インクリメント値の読み取りに失敗しました

挿入時にそのエラーをテストし、適切なアクションを実行できます。

45
outis

神経を落ち着かせるために、これを考慮してください:

ユーザーがWebサイトで何らかのトランザクションを実行するたびに新しい値を挿入するデータベースがあるとします。

64ビット整数をIDとして使用すると、これがオーバーフローの条件になります。世界人口が60億人の場合、地球上のすべての人間が毎日1秒間に1回(休憩なしで)トランザクションを実行すると、80以上の時間がかかりますIDがラップアラウンドするのに何年もかかります。

すなわち、コーヒーブレイク中に時々グーグルだけがこの問題を漠然と考慮する必要があります。

48
Justin

最大のIDを見ることで、いつオーバーフローするかがわかります。例外がスローされる前に変更する必要があります。

実際、最初から十分な大きさのデータ型を使用して設計する必要があります。最初から64ビットIDを使用しても、データベースのパフォーマンスが低下することはありません。

9
Matti Virkkunen

ここでの回答は何が起こるかを示していますが、問題を検出する方法を示す回答は1つだけです(エラーが発生した後のみ)。一般的に、これらが実稼働上の問題になる前に検出できると便利なので、オーバーフローが発生するタイミングを検出するクエリを作成しました。

SELECT
  c.TABLE_CATALOG,
  c.TABLE_SCHEMA,
  c.TABLE_NAME,
  c.COLUMN_NAME
FROM information_schema.COLUMNS AS c
JOIN information_schema.TABLES AS t USING (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME)
WHERE c.EXTRA LIKE '%auto_increment%'
  AND t.AUTO_INCREMENT / CASE c.DATA_TYPE
      WHEN 'TINYINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 255, 127)
      WHEN 'SMALLINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 65535, 32767)
      WHEN 'MEDIUMINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 16777215, 8388607)
      WHEN 'INT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 4294967295, 2147483647)
      WHEN 'BIGINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', '18446744073709551615', 9223372036854775807) # need to quote because column type defaults to unsigned.
      ELSE 0
    END > .9; # 10% buffer

これが誰かの助けになることを願っています。

6
CSTobey

MySQL 5.6の場合、 .6.9 AUTO_INCREMENTの使用 inは次のとおりです。

AUTO_INCREMENTカラムには、必要な最大シーケンス値を保持するのに十分な大きさの最小整数データ型を使用してください。列がデータ型の上限に達すると、シーケンス番号を生成する次の試行は失敗します。

0
Jingguo Yao