在設計主鍵的時候往往需要考慮以下幾點:
1.無意義性:此處無意義是從使用者的角度來定義的。這種無意義在一定程度上也會減少資料庫的資訊冗餘。常常有人稱呼主鍵為內部標識,為什麼會這樣稱呼,原因之一在於“內部”,所謂內部從某種程度上來說就是指表記錄,從大的範圍來說就是資料庫,如果你在設計的時候選擇了對使用者來說有意義的資訊來作為主鍵,那麼遲早會面對使用者提出對這塊資訊進行更新的需求,那麼你就違背了它應有的靜態。
2.靜態性:主鍵除了唯一地標識一條記錄及外鍵的關聯外,應不再考慮其他的意義,最理想的狀態就是在產生後不再變動,所以在主索引值產生後應考慮不對他進行更新等操作。如果進行了更新操作那麼至少說明這塊資訊對於使用者來說是有一定的意義,那麼你就違背了應有的無意義性。(對資料進行整合等操作時可能需要對主鍵進行處理,這樣做是為了保證資料庫的完整性——記錄的唯一,不在此考慮範圍之內。)
無意義性往往可以決定其靜態性。
3.簡短性:既包含主鍵組成欄位數量要少,還包含主鍵中單個欄位儲存類型簡短,一般採用整形;對於前者主要考慮的是外部索引鍵關聯的因素;對於後者主要考慮的是效能。主鍵的簡短對錶的關聯便捷性及檢索的效能有極大的協助。
看看下面具有缺陷的“主生產計劃表”主鍵設計方案(MsSQL): 複製代碼 代碼如下:--主表
CREATE TABLE PP_MPSHeader(
BillNo VARCHAR(20) NOT NULL PRIMARY KEY,
PlanDate DATETIME NOT NULL
)
--從表
CREATE TABLE PP_MPSBody(
BillNo VARCHAR(20) NOT NULL,
LineNumber SMALLINT NOT NULL,
ProductID INT NOT NULL,
ProductQty DECIMAL(18,2) NOT NULL,
PRIMARY KEY(BillNo,LineNumber)
)
--設定外鍵
ALTER TABLE PP_MPSBody
ADD CONSTRAINT FK_PP_MPSHeader_MPSBody FOREIGN KEY(BillNo) REFERENCES PP_MPSHeader(BillNo)
這是典型的主從表結構。主表記錄什麼時候下達哪個單號的主計劃,從表記錄的是此計劃生產哪些產品各多少數量,通過BillNo進行關聯。當使用者在下達一份主生產計劃後,很可能會發現由於粗心大意輸錯了BillNo中計劃單號資訊,那麼在他修改單號時,代碼編寫者需要在代碼中控制從表的單號跟隨主表的單號進行變動,否則單據將在外鍵的約束下無法儲存,如果沒有外鍵的約束,那麼資料將失去其完整性。
如果按照上面的3個注意點,解決方案如下(MsSQL): 複製代碼 代碼如下:--主表
CREATE TABLE PP_MPSHeader(
BillId INT PRIMARY KEY,
BillNo VARCHAR(20) NOT NULL,
PlanDate DATETIME NOT NULL
)
--從表
CREATE TABLE PP_MPSBody(
BillId INT PRIMARY KEY,
LineNumber SMALLINT NOT NULL,
ProductID INT NOT NULL,
ProductQty DECIMAL(18,2) NOT NULL,
PRIMARY KEY(BillId,LineNumber)
)
--設定外鍵
ALTER TABLE PP_MPSBody
ADD CONSTRAINT FK_PP_MPSHeader_MPSBody FOREIGN KEY(BillId) REFERENCES PP_MPSHeader(BillId)
現在,主從表通過BillId進行關聯,當產生一份生產計劃時,產生一個BillId,對於使用者來說根本沒有意義,在隨後單據資訊的改動中也不會出現上面的主從資訊協調問題。同時從表的資訊量小於上面的缺陷設計。因為原外鍵BillNo的長度從20個位元組變成了現在的BillId4個位元組,減少了資訊的冗餘。
這樣的例子其實很多,比如:
有的設計原材料表時,使用零組件圖號作為主鍵,那就意味著採購、生產、銷售等等相關表中都會出現零組件圖號的外鍵資訊,當零組件圖號資訊發生變動時,這些所有先關的資訊都需要跟著變動,這種缺陷如果不從根本上解決,那麼你可能需要寫個零組件圖號變動處理過程,來批量處理這些問題,在處理的過程中可能你還得考慮處理的順序問題……;
有的設計,使用身份證件號作為人員表的主鍵,但是身份證後來從15位變成了18位,這就意味著人員表中每個人的人員身份證資訊都需要變動,如果你是某個社保機構此應用程式的設計人員,那麼你就需要更新上百萬條記錄;那些所有由人員表通過身份證件號外聯出去的資訊記錄將會以億計數,那麼也許餘生你就不需要做其他工作了。
所以選擇無意義的索引值來作為主鍵的一部分,也是從長遠意義上來避免類似這種改動的發生。