2016-03-07 78 views
2

有一個簡單的表結構是這樣的:PostgreSQL的:SERIAL遞增失敗約束INSERT

CREATE TABLE test (
    id INT PRIMARY KEY, 
    sid SERIAL 
); 

我發現,如果我試圖插入行,但它沒有一個約束測試(即PRIMARY KEY約束),則SERIAL計數器無論如何都會增加,因此下一次成功插入sid將是sid + 2而不是sid + 1

這是正常的行爲嗎?任何方式來防止這種情況?

回答

9

是的,它是由設計。 Serial數據類型使用序列和這種行爲的文件(Sequence Manipulation Functions)中描述:

爲了避免阻斷獲得來自 相同序列號併發事務,nextval操作是從未回滾;也就是說,一旦 已取得一個值,即使後續執行nextval的 事務中止,它也被視爲使用。這意味着,中止 事務可能會在分配的 值序列中留下未使用的「漏洞」。

有沒有辦法有效地防止它。但是,您可以通過創建一個單行表並在獲取下一個值時鎖定它來開發自己的序列。