2011-04-28 83 views
12

我們有一張表,主鍵爲auto-increment int,其最大值現在處於T-SQL int類型的限制範圍內。當我們嘗試對錶格進行重新播種時(因爲按鍵中存在很大的間隙,遠遠不及最接近的行數),它以某種方式不斷重置爲最大值。當主鍵溢出時,你會做什麼?

很明顯,這會導致嚴重的問題。 PK永遠不應該得到這個值,改變數據類型將是一項重大任務。重播應該足夠了,但它不起作用!

它如何不斷重置?

編輯:爲了澄清情況,此查詢SELECT MIN(CategoryID), MAX(CategoryID) FROM dbo.tblCategories返回-2147483647,21147483647 ...意味着在類型的最小值和最大值處有實際的PK值。

+0

什麼是最大的使用價值?我的猜測是,它是存儲在int中的最大值。 – 2011-04-28 15:26:02

+0

我明確了這個帖子。 – 2011-04-28 15:34:55

+1

如何重新填充列,是否運行DBCC CHECKIDENT(TABLE_NAME,RESEED,NEW_SEED_VALUE)?也許你的身份提升值很高,你有沒有注意到你數據中的差距? – 2011-04-28 15:38:37

回答

6

您可以「重新填寫」一個表,以便下一個分配的標識列將小於表中的當前最大值。但是,任何後續DBCC CHECKIDENT會將內部計數器重置回當前列中的最大值。也許這就是重置來自哪裏?當然,插頁最終會達到重複價值,導致生產支持團隊感興趣的時代。

總的來說,你遇到了麻煩。我建議使用一次性腳本來刪除/重置超高ID值。更新行(和所有相關的外鍵值)是一種選擇,但它會涉及禁用外鍵約束,我不知道其他什麼,所以我不會推薦它。另一種方法是使用更實用的Id值爲「高ID」項目創建全部的確切副本,然後刪除原始條目。這是一個黑客攻擊,但它會導致一個更可維護的數據庫。

哦,並追蹤那些把這些高ID值放進去的人,並且 - 至少 - 撤銷他們對數據庫的訪問權。

+1

重新編排表格也可能會重置身份計數器,正如其他維護類型的活動一樣。可能需要進行大量測試才能確定實際導致重新設置的內容。 – 2011-04-28 15:58:55

+0

我想有人不小心在不使用'NORESEED'的情況下運行'CHECKIDENT',但它不是基於我們所擁有的錯誤日誌中的時間戳。 – 2011-04-28 16:09:20

+1

看起來我們很幸運,並且表的PK沒有被用作任何地方的外鍵。由於這個事實,我們可以從1開始計算PK數。 – 2011-04-28 17:34:35

0

創建一個具有相同結構的新表。從舊到新閱讀(PK除外)。然後刪除舊的並重命名新的。

+7

...同時打破所有現有的外鍵關係... – Heinzi 2011-04-28 15:28:58

+0

正如海因茲所言,這會完全破壞參照完整性。 – 2011-04-28 15:37:37

+2

..以及原始帖子中沒有提及FKs ... – ethrbunny 2011-04-29 11:27:37

3

我曾經參與過一個有類似問題的項目 - 雖然在我們的例子中,有人選擇了一個4位數的字段作爲主鍵,當我們接近9999條記錄時,這種情況並不奏效。

在我們的例子中,我們在表上創建了一個新列,並填充它,將主鍵更改爲該列,並將所有外鍵關係重新命名爲新鍵。

非常混亂,但它確實有效。