2

私はSQLServerとPostgreSQLの両方で実行するアプリケーションを作成しているので、両方についてこの質問をしています。

(シーケンスまたは自動インクリメントタイプのものを使用して)一意の主キーを作成し、40億レコード(32ビット)を超えるとどうなりますか?テーブルに40億のレコードがあると言っているのではなく、RIDが増加するだけなので、40億のレコードが作成されていると言っています。したがって、これらのレコードを39億個削除しても、RIDは40億の範囲にあります。では、どうなりますか?精度を64ビットに上げますか、それとも0にロールオーバーしますか、それとも非常に重大なエラーを吐き出しますか?64ビットのRIDでも最終的にオーバーフローする可能性があることを心配する必要がありますか?

また、どうすればこれと戦うことができますか?何らかのクリーンアップオプションやツールはありますか?一貫したRIDを取得するには、毎年独自のものを作成する必要がありますか、それともテーブルを完全に再構築する必要がありますか?(したがって、これらのRIDを使用する他の多くのテーブルも外部キーです)

4

2 に答える 2

3

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バイト整数の範囲(-9223372036854775808〜9223372036854775807)を超えることはできません。一部の古いプラットフォームでは、8バイト整数のコンパイラサポートがない場合があります。その場合、シーケンスは通常の整数演算(範囲-2147483648〜 + 2147483647)を使用します。

ただし、それを循環させることができます。

CYCLEオプションを使用すると、昇順または降順のシーケンスがそれぞれ最大値または最小値に達したときに、シーケンスをラップアラウンドできます。制限に達すると、次に生成される数値はそれぞれ最小値または最大値になります。

NO CYCLEが指定されている場合、シーケンスが最大値に達した後にnextvalを呼び出すと、エラーが返されます。CYCLEもNOCYCLEも指定されていない場合、デフォルトはNOCYCLEです。

それと戦わないでください。余分なバイトを使い、物事をシンプルに保ちます。キースペースを大きくするよりも、複雑さやメンテナンスタスクのレイヤーを追加したことを後悔する可能性が高くなります。

于 2009-12-29T21:23:22.500 に答える
1

SQL Serverの場合:RID列のタイプによって異なります。内部IDENTITYはインクリメントできますが、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')
于 2009-12-29T21:20:01.070 に答える