![](/img/trans.png)
[英]Add a column to composite primary key that is also a foreign key in other tables
[英]Changing a table's primary key column referenced by foreign key in other tables
在我們的數據庫中(在 SQL Server 2005 上)我們有一個“客戶”表,其主鍵是客戶代碼,代理項,bigint IDENTITY(1,1) 鍵; 該表被我們數據庫中的許多其他表通過外鍵引用。
我們估計的一個新的 CR 實現需要我們將 ID 列類型更改為 varchar,客戶端代碼生成算法從簡單的數字級數轉換為嚴格的 2 字符表示,代碼范圍從 01 到 99,然后進展如下:
1A -> 2A -> ... -> 9A -> 1B -> ... 9Z
我對數據庫設計相當陌生,但我在這里聞到了一些嚴重的問題。 首先,這個客戶端代碼生成算法呢? 如果我需要超出 9Z 代碼限制的 go 的客戶代碼怎么辦?
我有一個問題:這種改變是否可行,表已經填充了相當數量的數據,並被多個實體引用? 如果是這樣,您將如何解決這個問題,以及您將如何實現客戶端代碼生成?
我對您提議的最大擔憂是您將被限制為 360 條主要記錄。 這似乎是一個很小的數字。
執行更改是一個多步驟操作。 您需要在核心表及其所有相關表中創建新字段。
要進行就地更新,您需要在核心表中生成代碼。 然后您需要更新所有相關表以具有基於舊id 的代碼。 然后您需要將外鍵約束添加到所有相關表中。 然后您需要從所有相關表中刪除舊的關鍵字段。
我們只在我們的開發服務器中這樣做了。 當我們升級實時數據庫時,我們為每個數據庫創建了一個新數據庫,並使用查詢舊數據庫並插入新數據庫的 python 腳本復制數據。 我現在為每次軟件升級更新該腳本,以便核心引擎保持不變,但我可以指定不同的表或數據修改。 如果在升級生產時發生意外情況,我可以獲得原始數據庫的完整備份。
支持非身份/指導代碼的一個強有力的論據是,您需要一個人類可讀/可記憶的代碼,並且您需要能夠在兩個系統之間移動記錄。
在 SQL Server 2005 和 2008 中,性能不一定是一個問題。我們最近進行了一次更改,我們從無處不在的 int id 移動到 7 或 8 個字符的“友好”記錄代碼。 我們預計會看到某種性能下降,但實際上我們看到了性能提升。
我們還發現我們需要一種快速生成代碼的方法。 我們的代碼有兩部分,一個 3 個字符的字母前綴和一個 4 或 5 位數字的后綴。 一旦我們有大量代碼(15000-20000),我們發現將代碼解析為前綴和后綴並找到最低未使用的代碼會很慢(需要幾秒鍾)。 正因為如此,我們還將前綴和后綴分開存儲(在主鍵表中),以便我們可以快速找到具有特定前綴的下一個可用的最低代碼。 緩存的前綴和后綴使搜索幾乎收費。
我們允許更改代碼,並且它們更改的值通過外鍵關系上的級聯更新規則傳播。 我們在核心代碼表上保留了一個身份密鑰,以簡化代碼的更新。
我們不使用 ORM,所以我不知道需要注意哪些具體事項。 在我們最大的實例中,我們也有大約 60,000 個主鍵,但是有數百個相關的表和具有數百萬個與代碼表相關的值的表。
我們獲得的一大優勢是,在許多情況下,我們不需要執行連接即可執行操作。 在軟件的任何地方,用戶都通過友好的代碼引用事物。 我們不必查找 int ID(或連接)來執行某些操作。
新的代碼生成算法不值得考慮。 您可以編寫一個程序,只需幾行代碼即可生成所有可能的代碼。 把它們放在一張桌子上,你就完成了。 您只需要編寫一個 function 即可返回尚未使用的最小的。 這是一個 Ruby 程序,它將為您提供所有可能的代碼。
# test.rb -- generate a peculiar sequence of two-character codes.
i = 1
('A'..'Z').each do |c|
(1..9).each do |n|
printf("'%d%s', %d\n", n, c, i)
i += 1
end
end
該程序將創建一個 CSV 文件,您應該能夠輕松地將其導入表中。 您需要兩列來控制排序順序。 新值不會自然地按照您的要求指定的方式排序。
我更關心范圍而不是算法。 如果您的要求是正確的,那么您將被限制為 234 個客戶端代碼。 如果你錯了,范圍從“1A”延伸到“ZZ”,你被限制在不到一千。
要在現有表中實現此要求,您需要遵循一個謹慎的過程。 在生產表上嘗試之前,我會在測試環境中嘗試幾次。 (這只是一個草圖。有很多細節。)
NOT NULL UNIQUE
或PRIMARY KEY
約束和新的FOREIGN KEY
約束。沒有真正解決這是否是一個好主意,但您可以更改外鍵以級聯更新。 完成后會發生什么,當您更新父表中的主鍵時,子表中的相應鍵將相應更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.