76

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

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

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

4

6 に答える 6

55

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

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

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

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

于 2011-05-16T09:26:33.667 に答える
55

§3.6.9からのジムマーティンのコメント。MySQLドキュメントの「AUTO_INCREMENTの使用」:

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

MySQL 5.1.45で簡単にテストすると、次のエラーが発生します。

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

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

于 2010-04-11T00:10:25.720 に答える
11

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

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

于 2010-04-10T23:42:14.577 に答える
8

ここでの回答は何が起こるかを示していますが、問題を検出する方法を示しているのは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

これがどこかで誰かを助けることを願っています。

于 2017-07-18T16:00:22.790 に答える
0

MySQL 5.6の場合、3.6.9でAUTO_INCREMENTを使用すると次のようになります。

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

于 2015-09-23T08:29:22.680 に答える
-1

これについて私が今経験した個人的な経験を共有したいと思います。Nagios + Check_MK+NDOUtilsを使用します。NDOUtilsは、すべてのチェックをnagios_servicechecksというテーブルに保存します。主キーは、署名されたauto_incrementintです。この制限が範囲内にある場合、MySQLはどうなりますか?さて、私の場合、MySQLは最後のレコードを除くすべてのレコードを削除します。テーブルはほとんど空になりました。新しいレコードが挿入されるたびに、古いレコードは削除されます。なぜこれが起こるのかはわかりませんが、実際にはすべての記録を失いました。Icinga(Nagiosではない)で使用されるIDOUtilsは、bigintによってintを変更するこの問題を修正しました。エラーは発生しませんでした。

于 2015-11-26T18:33:53.770 に答える