簡體   English   中英

SQL Server中斷分配的標識種子增量?

[英]SQL Server breaks the assigned identity seed increment?

我有兩個表: table1 (列id :種子1000,增量1)和table2 (列id :種子2000,增量1)。 首先,我在table1table2插入一些記錄。 其次,我在table1插入table2 (使用identity_insert_on ),並得到如下信息:

1000 first_record_table1
1001 second_record_table1
1002 third_record_table1
2000 first_record_table2
2001 second_record_table2

第三:如果我在表1中添加新記錄,我希望獲得1003作為新ID,但我得到2002。(1003沒有違反唯一ID規則,並且是表1的正確增量值,因此我看不到任何記錄跳到最后一個記錄並遞增1的原因,就像數據庫似乎這樣做的那樣)。

問題:如何獲得1003作為新ID?

關於identity文檔非常清楚:

列上的identity屬性不能保證滿足以下條件:

  • 值的唯一性–必須通過使用PRIMARY KEY或UNIQUE約束或UNIQUE索引來強制執行唯一性。

  • 事務內的連續值–不能保證插入多行的事務會獲得行的連續值,因為表上可能會發生其他並發插入。 如果值必須是連續的,則事務應在表上使用排他鎖或使用SERIALIZABLE隔離級別。

  • 服務器重新啟動或其他故障后的連續值–由於性能原因,SQL Server可能會緩存標識值,並且在數據庫故障或服務器重新啟動期間某些分配的值可能會丟失。 這可能導致插入時身份值出現空白。 如果差距不可接受,則應用程序應使用帶有NOCACHE選項的序列生成器,或使用其自己的機制生成鍵值。

  • 值的重用–對於具有特定種子/增量的給定身份屬性,引擎不會重用身份值。 如果特定的插入語句失敗或插入語句回滾,則使用的標識值將丟失並且不會再次生成。 當生成后續標識值時,這可能會導致出現間隙。

在大多數情況下, identity primary key列可以完成其預期的工作。 當插入新行時,它將創建一個大於任何先前值的新值。 可能存在差距,但這對於主鍵來說不是問題。

如果要填充空白的列,則必須編寫觸發器以分配值。

另外,您可以在查詢中使用row_number()來獲取順序值。

增量1僅表示下一條記錄的ID比最大的ID大一個,而不是將使用所有數字。 如果要使用1003作為新ID,則必須自己進行一些編程,並處理達到2000時已經采用新ID的情況。

但是,您永遠不應依賴任何生成的ID。 假設您有2節課。 第一個會話插入了一些內容,尚未提交或回滾。 第二會話插入一些東西並提交。 第一屆會議回滾。 您要如何處理這種情況? 您將需要為第一個會話分配一些ID,為第二個會話分配一個不同的ID。 現在,第一個會話回滾,因此其ID未使用。 您是否要從第二個會話的ID中減去一個? 好主意。 阻止第二個會話,直到第一個會話回滾或提交? 也是個壞主意。

因此,請忘記連續的ID,它們將永遠無法使用。 唯一的ID通常是您需要的,並且SQL Server保證它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM