テーブル内のフィールドが符号付きまたは符号なしの最大32ビット整数に近づいたらどうしますか?


14

一意の自動インクリメントフィールドの形式でユーザーレコードを保持する任意のデータベース(たとえば、ユーザー間メッセージ)...現在のデータ型の?(32ビットINT)?次のエントリに(2∧32)-1の番号を割り当てようとすると、データベースサーバーがオーバーフローするのではないかと推測しています。レコードを追加し続けますか?あなたならどうしますか?

たとえば、VARCHARSではなくINTを使用するのはなぜですか?

この架空の質問を自問してから数日が経ちましたが、専門家が何をするのか知りたいです。

回答:


12

通常、varcharsではなく整数を使用します。スペースを消費せず、ソートパターンがインデックス付けなどに高速であることをよく理解しているためです。整数はCPUの自然なデータ型であり、したがってパフォーマンスは一般的に最適です。通常、整数は4バイトで、(非Unicode)varcharの4文字だけに相当します。

INT型でスペースが不足することが心配な場合は、BIGINTを試してください。8バイトの数値が得られます。これの制限は非常に大きく、そのレコードの制限に達する前におそらくディスク容量が不足するでしょう:-) BIGINTのパフォーマンスも非常に良くなります。特に多くのサーバーが64ビットになっているためです。 。

特にデータ型をBIGINTに変更せずに言ったように、INTを使い果たしたときに何が起こるかについての質問の最初の部分に対する答えは簡単ではありません。基本的に、できることはあまりありません。できることは、データベース内のデータの性質によって非常に制限されています。このデータの外部キーはどのレコードですか?そのテーブルのすべてのデータと関連レコードがまだ必要ですか?多くの初期データ(およびその関連データ)をアーカイブできると仮定した場合、提案できる唯一のことは、データをテーブルから移動することです(最初の1〜100万レコードを言う)。 IDシードを1にリセットします。さまざまな理由がありますが、それはお勧めしませんが、たとえば、idフィールドの最大値をチェックするなど、コードの多くのビットがあります。追加されたばかりのものを確認するために、それは機能しません(実行すべきではありません)。また、人々は、レコードNがN + 1の前に作成されたと仮定します。簡単な答えはないと思います。

最後に、MySQLについては知りませんが、制限に達するとSQL Serverはオーバーフローエラーを返します。


1
このような詳細な答えに満足しています。VARCHAR、INT、およびBIGINT取引の説明をありがとう。この質問は仮説に基づいているため、BIGINTの制限に到達した場合はどうなるのかと思います。この質問は、私がINTを使用して限界に達したFacebookについて見た投稿によって提起されました。アーカイブは機能するか、条件付きステートメントで2番目のテーブルを作成します(前述のように、スクリプトも更新する必要があり、かなり複雑になります)。全体として、素晴らしい答えです。お時間をいただきありがとうございます。
エアロクロス

9

見落とされがちな点の1つは、多くの人が自動番号またはIDを1から開始するため、可能な範囲の半分がすぐに失われることです(署名済みの場合)

この場合、-1から始まるように単純に番号を再定義します。

おそらく、ID列を埋めることを期待している場合は、最初にこれを設計し、より広いデータ型を使用する必要がありました。

この最近の質問をご覧くださいSO:SQL Server 2008:IDがintの最大値を超えた場合はどうなりますか?


より広いデータ型を使用するのは論理的です(どのくらいの量のデータを使用するテーブルの場合)が、それは仮説的な質問であるため、洞察が必要でした。署名されている場合、それはうまくいくかもしれませんが(負の数の主キーを持っていると私は少し奇妙になります)、私はそれがかなり賢いと思います。DBAが肯定的なデータをアーカイブして再起動する時間を与えます。署名されていない場合は、まあ...問題。
エアロクロス

-1から-1の増分を使用する代わりに、(-2147483648)から開始して1ずつ増分します。新しい大きなものと。そして、もしあなたが無署名のBIGINTを渡すなら、私はあなたのチームで働きたいです;)
jcolebrand

PostgreSQLはシーケンスを使用してID番号を生成します。CREATE SEQUENCEステートメントを使用すると、CYCLEを指定できます。CYCLEは、最大値に達した場合にラップアラウンドします。(または、他の方向に進む場合の最小値。)CYCLEオプションは、現在SQL標準に含まれています。(少なくとも2003年以降)
マイクシェリル 'キャットリコール'

4

オーバーフローBIGINT?ハハ。最初に不滅を達成する方法を見つけてください。INT UNSIGNED(40億)は到達するのに十分困難です。1秒あたり100のINSERTは、1年でINTのオーバーフローに近づきます。BIGINTには数十億年かかります。

修正するには:ALTER TABLE foo MODIFY COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT; しかし、テーブル(40億行近くあります)をコピーし、すべてのセカンダリインデックスを再構築するため、これには数時間かかります。計画アヘアd。

一般に、フィールドに対して大きすぎる数値(たとえば、TINYINT UNSIGNEDの999)を保存しようとすると、フィールドの最大値(この場合は255)に暗黙のうちに上限が設定されます。「警告」があるかもしれませんが、ほとんどの人は警告を確認することを気にしません。UNIQUEフィールドの場合、または外部キーがある場合、より深刻なエラーが発生する可能性があります。

CHARまたはVARCHARは、使用可能なスペースに切り捨てられます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.