2009-12-29 29 views
2

我正在製作一個在SQL Server和PostgreSQL上運行的應用程序,所以我在問這個問題。獨特的RID會「溢出」嗎?

每當你創建一個唯一的主鍵(使用序列或自動增量類型的東西)並且你擊中了超過40億條記錄(32位)時會發生什麼?我並不是說我們的表格將有40億條記錄,而是因爲RID只增加而創建了40億條記錄。所以即使我刪除了39億條記錄,我的RID仍然在40億的範圍內。那麼會發生什麼?它是否提高了64位的精度,或者它是否回滾到0或只是吐出一個非常嚴重的錯誤?我是否應該擔心即使64位RID最終也會溢出?

另外,我該如何反擊呢?是否有某種清理選項或工具?我是否每年都要創建自己的東西?完全重建表以獲得一致的RID? (因此也觸及很多使用這些RID的其他表是外鍵)

+2

是的,32位自動增量值會溢出。 http://stackoverflow.com/questions/261815/upper-limit-for-autoincrement-primary-key-in-sql-server – jball 2009-12-29 21:17:40

+0

你將無法在你的整個生活中溢出64位數字,它只是太大。 – 2009-12-29 21:26:02

+1

在我一生中?還是在大約10年?當數據庫充滿非常關鍵的數據時,我絕對不會想要在10年內修復這個bug – Earlz 2009-12-29 21:29:01

回答

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) 

從文檔:

Sequences are based on bigint arithmetic, so the range cannot exceed the range of an eight-byte integer (-9223372036854775808 to 9223372036854775807). On some older platforms, there might be no compiler support for eight-byte integers, in which case sequences use regular integer arithmetic (range -2147483648 to +2147483647).

然而,你可以讓它循環:

The CYCLE option allows the sequence to wrap around when the maxvalue or minvalue has been reached by an ascending or descending sequence respectively. If the limit is reached, the next number generated will be the minvalue or maxvalue, respectively.

If NO CYCLE is specified, any calls to nextval after the sequence has reached its maximum value will return an error. If neither CYCLE or NO CYCLE are specified, NO CYCLE is the default.

不要打它。花費額外的字節並保持簡單。與更大的密鑰空間相比,您更可能會後悔添加額外的複雜性和/或維護任務。

1

在SQL Server上:它取決於RID列的類型。該內部身份可以增加,但將無法分配給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')