2016-08-04 14 views
2

我在Django中有Booking模型,它的ID是Django創建的內置id列。下面是它的外觀在數據庫級Postgres裏:爲什麼模型ID始終是Postgres/Django中下一個遞增的數字?

integer not null default nextval('bookings_booking_id_seq'::regclass) 

客戶端已調用今天擔心的是,這些數字似乎是連續的,但並不總是連續的。例如,序列如下:

..2, ..3, ..4, ..6, ..8, ..9 

他們擔心繫統正在刪除或刪除預訂。 ..5..7在哪裏?我們將[一般] 所有內容都記錄在之內,可以刪除預訂,所以我相當有信心,這不是系統問題。程序員的直覺也教會了我不要期待Auto-IDs的連續性,但單憑直覺對客戶的解釋還不夠好。

是否存在技術原因Postgres在分配這些ID時會跳過數字?

+2

這是正常的,當事務回滾等時,序列中可能會有* holes *。技術原因是這樣序列是無鎖的(否則它可能成爲鎖定熱點或漏斗)。 – joop

回答

4

postgres docs

因爲smallserial,串行和BIGSERIAL使用序列可能有「洞」或間隙值,其出現在列序列中實現的,即使沒有行是曾被刪除。即使包含該值的行永遠不會成功插入表列,但從該序列分配的值仍會「用完」。例如,如果插入事務回滾,則可能發生這種情況。有關詳細信息,請參見第9.16節中的nextval()。

並且還從文檔爲nextval

爲了避免阻斷獲得來自同一序列號併發事務,nextval操作是從未回滾;也就是說,一旦取得一個值,就認爲它已被使用,不會再被返回。即使周圍事務稍後中止,或者如果調用查詢最終不使用該值,情況也是如此。例如,帶有ON CONFLICT子句的INSERT將在檢測到任何會導致它遵循ON CONFLICT規則的衝突之前計算待插入的元組,包括執行任何所需的nextval調用。這種情況會在指定值序列中留下未使用的「漏洞」。因此,PostgreSQL序列對象不能用來獲得「無間隙」序列。

相關問題