ユニークなリッドは「オーバーフロー」しますか?
-
21-09-2019 - |
質問
SQL ServerとPostgreSQLの両方で実行するアプリケーションを作成しているため、両方についてこの質問をしています。
一意のプライマリキー(シーケンスまたは自動インクリメントタイプのものを使用して)を作成し、40億件以上のレコード(32ビット)を押した場合はどうなりますか?私たちのテーブルには40億の記録があると言っているのではなく、むしろ40億の記録が作成されていると言っています。したがって、これらの記録の39億を削除したとしても、私のRIDはまだ40億の範囲にあります。では、どうなりますか?精度を64ビットに上げますか、それとも0にロールオーバーしますか、それとも非常に重要なエラーを吐き出しますか? 64ビットのRIDでも最終的にオーバーフローする可能性があることを心配する必要がありますか?
また、どうすればこれと戦うことができますか? ある種のクリーンアップオプションまたはツールはありますか?一貫したリドを得るために、毎年自分のものを作成する必要がありますか?テーブルを完全に再構築する必要がありますか? (したがって、これらのRIDを使用する他の多くのテーブルにも触れてください)
解決
PostgreSQLは、デフォルトではエラーではなく、オーバーフローしません。
# create sequence willyouwrap;
CREATE SEQUENCE
# select setval('willyouwrap', 9223372036854775807);
setval
---------------------
9223372036854775807
(1 row)
# select nextval('willyouwrap');
ERROR: nextval: reached maximum value of sequence "willyouwrap" (9223372036854775807)
ドキュメントから:
シーケンスはBigInt算術に基づいているため、範囲は8バイトの整数(-922372036854775808から9223372036854775807の範囲を超えることはできません。一部の古いプラットフォームでは、8バイト整数のコンパイラサポートがない場合があります。この場合、通常の整数算術(範囲-2147483648〜 +2147483647)を使用します。
ただし、サイクルすることができます。
サイクルオプションにより、シーケンスは、それぞれ昇順または下降シーケンスによってMaxValueまたはMinValueに到達したときにラップします。制限に達した場合、生成される次の数値はそれぞれMinValueまたはMaxValueになります。
サイクルが指定されていない場合、シーケンスが最大値に達した後にNextvalへの呼び出しはエラーを返します。サイクルもサイクルも指定されていない場合、サイクルはデフォルトではありません。
戦わないでください。余分なバイトを費やして、物事をシンプルに保ちます。より大きなキースペースを持っているよりも、複雑さやメンテナンスタスクの余分な層を追加したことを後悔する可能性が高くなります。
他のヒント
SQL Serverでは、RID列のタイプに依存します。内部IDは増分できますが、Stoarge列に割り当てられません。
CREATE TABLE [t1] (
[tid] int IDENTITY (2147483647, 1) NOT NULL
, name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')
これはエラーをトリガーします:
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
しかし、十分なストレージを備えた数値列は、正常に増加します。
CREATE TABLE [t1] (
[tid] numeric(38,0) IDENTITY (2147483647, 1) NOT NULL
, name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')
同様に、Bigintは2 ^^ 63-1でオーバーフォーします:
CREATE TABLE [t1] (
[tid] bigint IDENTITY (9223372036854775807, 1) NOT NULL
, name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')
しかし、十分なストレージを備えた数値列が成功します。
CREATE TABLE [t1] (
[tid] numeric(38,0) IDENTITY (9223372036854775807, 1) NOT NULL
, name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')