sqlserver主鍵設(shè)計的注意點
更新時間:2012年07月27日 09:27:02 作者:
在數(shù)據(jù)庫設(shè)計中,主鍵用于惟一地標識表中的某一條記錄
在設(shè)計主鍵的時候往往需要考慮以下幾點:
1.無意義性:此處無意義是從用戶的角度來定義的。這種無意義在一定程度上也會減少數(shù)據(jù)庫的信息冗余。常常有人稱呼主鍵為內(nèi)部標識,為什么會這樣稱呼,原因之一在于“內(nèi)部”,所謂內(nèi)部從某種程度上來說就是指表記錄,從大的范圍來說就是數(shù)據(jù)庫,如果你在設(shè)計的時候選擇了對用戶來說有意義的信息來作為主鍵,那么遲早會面對用戶提出對這塊信息進行更新的需求,那么你就違背了它應(yīng)有的靜態(tài)。
2.靜態(tài)性:主鍵除了唯一地標識一條記錄及外鍵的關(guān)聯(lián)外,應(yīng)不再考慮其他的意義,最理想的狀態(tài)就是在產(chǎn)生后不再變動,所以在主鍵值產(chǎn)生后應(yīng)考慮不對他進行更新等操作。如果進行了更新操作那么至少說明這塊信息對于用戶來說是有一定的意義,那么你就違背了應(yīng)有的無意義性。(對數(shù)據(jù)進行整合等操作時可能需要對主鍵進行處理,這樣做是為了保證數(shù)據(jù)庫的完整性——記錄的唯一,不在此考慮范圍之內(nèi)。)
無意義性往往可以決定其靜態(tài)性。
3.簡短性:既包含主鍵組成字段數(shù)量要少,還包含主鍵中單個字段存儲類型簡短,一般采用整形;對于前者主要考慮的是外鍵關(guān)聯(lián)的因素;對于后者主要考慮的是性能。主鍵的簡短對表的關(guān)聯(lián)便捷性及檢索的性能有極大的幫助。
看看下面具有缺陷的“主生產(chǎn)計劃表”主鍵設(shè)計方案(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)
)
--設(shè)置外鍵
ALTER TABLE PP_MPSBody
ADD CONSTRAINT FK_PP_MPSHeader_MPSBody FOREIGN KEY(BillNo) REFERENCES PP_MPSHeader(BillNo)
這是典型的主從表結(jié)構(gòu)。主表記錄什么時候下達哪個單號的主計劃,從表記錄的是此計劃生產(chǎn)哪些產(chǎn)品各多少數(shù)量,通過BillNo進行關(guān)聯(lián)。當用戶在下達一份主生產(chǎn)計劃后,很可能會發(fā)現(xiàn)由于粗心大意輸錯了BillNo中計劃單號信息,那么在他修改單號時,代碼編寫者需要在代碼中控制從表的單號跟隨主表的單號進行變動,否則單據(jù)將在外鍵的約束下無法保存,如果沒有外鍵的約束,那么數(shù)據(jù)將失去其完整性。
如果按照上面的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)
)
--設(shè)置外鍵
ALTER TABLE PP_MPSBody
ADD CONSTRAINT FK_PP_MPSHeader_MPSBody FOREIGN KEY(BillId) REFERENCES PP_MPSHeader(BillId)
現(xiàn)在,主從表通過BillId進行關(guān)聯(lián),當產(chǎn)生一份生產(chǎn)計劃時,生成一個BillId,對于用戶來說根本沒有意義,在隨后單據(jù)信息的改動中也不會出現(xiàn)上面的主從信息協(xié)調(diào)問題。同時從表的信息量小于上面的缺陷設(shè)計。因為原外鍵BillNo的長度從20個字節(jié)變成了現(xiàn)在的BillId4個字節(jié),減少了信息的冗余。
這樣的例子其實很多,比如:
有的設(shè)計原材料表時,使用零部件圖號作為主鍵,那就意味著采購、生產(chǎn)、銷售等等相關(guān)表中都會出現(xiàn)零部件圖號的外鍵信息,當零部件圖號信息發(fā)生變動時,這些所有先關(guān)的信息都需要跟著變動,這種缺陷如果不從根本上解決,那么你可能需要寫個零部件圖號變動處理過程,來批量處理這些問題,在處理的過程中可能你還得考慮處理的順序問題……;
有的設(shè)計,使用身份證件號作為人員表的主鍵,但是身份證后來從15位變成了18位,這就意味著人員表中每個人的人員身份證信息都需要變動,如果你是某個社保機構(gòu)此應(yīng)用程序的設(shè)計人員,那么你就需要更新上百萬條記錄;那些所有由人員表通過身份證件號外聯(lián)出去的信息記錄將會以億計數(shù),那么也許余生你就不需要做其他工作了。
所以選擇無意義的鍵值來作為主鍵的一部分,也是從長遠意義上來避免類似這種改動的發(fā)生。
1.無意義性:此處無意義是從用戶的角度來定義的。這種無意義在一定程度上也會減少數(shù)據(jù)庫的信息冗余。常常有人稱呼主鍵為內(nèi)部標識,為什么會這樣稱呼,原因之一在于“內(nèi)部”,所謂內(nèi)部從某種程度上來說就是指表記錄,從大的范圍來說就是數(shù)據(jù)庫,如果你在設(shè)計的時候選擇了對用戶來說有意義的信息來作為主鍵,那么遲早會面對用戶提出對這塊信息進行更新的需求,那么你就違背了它應(yīng)有的靜態(tài)。
2.靜態(tài)性:主鍵除了唯一地標識一條記錄及外鍵的關(guān)聯(lián)外,應(yīng)不再考慮其他的意義,最理想的狀態(tài)就是在產(chǎn)生后不再變動,所以在主鍵值產(chǎn)生后應(yīng)考慮不對他進行更新等操作。如果進行了更新操作那么至少說明這塊信息對于用戶來說是有一定的意義,那么你就違背了應(yīng)有的無意義性。(對數(shù)據(jù)進行整合等操作時可能需要對主鍵進行處理,這樣做是為了保證數(shù)據(jù)庫的完整性——記錄的唯一,不在此考慮范圍之內(nèi)。)
無意義性往往可以決定其靜態(tài)性。
3.簡短性:既包含主鍵組成字段數(shù)量要少,還包含主鍵中單個字段存儲類型簡短,一般采用整形;對于前者主要考慮的是外鍵關(guān)聯(lián)的因素;對于后者主要考慮的是性能。主鍵的簡短對表的關(guān)聯(lián)便捷性及檢索的性能有極大的幫助。
看看下面具有缺陷的“主生產(chǎn)計劃表”主鍵設(shè)計方案(MsSQL):
復(fù)制代碼 代碼如下:
--主表
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)
)
--設(shè)置外鍵
ALTER TABLE PP_MPSBody
ADD CONSTRAINT FK_PP_MPSHeader_MPSBody FOREIGN KEY(BillNo) REFERENCES PP_MPSHeader(BillNo)
這是典型的主從表結(jié)構(gòu)。主表記錄什么時候下達哪個單號的主計劃,從表記錄的是此計劃生產(chǎn)哪些產(chǎn)品各多少數(shù)量,通過BillNo進行關(guān)聯(lián)。當用戶在下達一份主生產(chǎn)計劃后,很可能會發(fā)現(xiàn)由于粗心大意輸錯了BillNo中計劃單號信息,那么在他修改單號時,代碼編寫者需要在代碼中控制從表的單號跟隨主表的單號進行變動,否則單據(jù)將在外鍵的約束下無法保存,如果沒有外鍵的約束,那么數(shù)據(jù)將失去其完整性。
如果按照上面的3個注意點,解決方案如下(MsSQL):
復(fù)制代碼 代碼如下:
--主表
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)
)
--設(shè)置外鍵
ALTER TABLE PP_MPSBody
ADD CONSTRAINT FK_PP_MPSHeader_MPSBody FOREIGN KEY(BillId) REFERENCES PP_MPSHeader(BillId)
現(xiàn)在,主從表通過BillId進行關(guān)聯(lián),當產(chǎn)生一份生產(chǎn)計劃時,生成一個BillId,對于用戶來說根本沒有意義,在隨后單據(jù)信息的改動中也不會出現(xiàn)上面的主從信息協(xié)調(diào)問題。同時從表的信息量小于上面的缺陷設(shè)計。因為原外鍵BillNo的長度從20個字節(jié)變成了現(xiàn)在的BillId4個字節(jié),減少了信息的冗余。
這樣的例子其實很多,比如:
有的設(shè)計原材料表時,使用零部件圖號作為主鍵,那就意味著采購、生產(chǎn)、銷售等等相關(guān)表中都會出現(xiàn)零部件圖號的外鍵信息,當零部件圖號信息發(fā)生變動時,這些所有先關(guān)的信息都需要跟著變動,這種缺陷如果不從根本上解決,那么你可能需要寫個零部件圖號變動處理過程,來批量處理這些問題,在處理的過程中可能你還得考慮處理的順序問題……;
有的設(shè)計,使用身份證件號作為人員表的主鍵,但是身份證后來從15位變成了18位,這就意味著人員表中每個人的人員身份證信息都需要變動,如果你是某個社保機構(gòu)此應(yīng)用程序的設(shè)計人員,那么你就需要更新上百萬條記錄;那些所有由人員表通過身份證件號外聯(lián)出去的信息記錄將會以億計數(shù),那么也許余生你就不需要做其他工作了。
所以選擇無意義的鍵值來作為主鍵的一部分,也是從長遠意義上來避免類似這種改動的發(fā)生。
相關(guān)文章
Sql Server 存儲過程調(diào)用存儲過程接收輸出參數(shù)返回值
這篇文章主要介紹了Sql Server 存儲過程調(diào)用存儲過程接收輸出參數(shù)返回值,需要的朋友可以參考下2017-06-06
sql 函數(shù)大全 比較常用的一些函數(shù)整理
學習sqlserver的朋友,可以參考下,掌握這些函數(shù)可以方便的對字段的字符進行處理。2010-04-04
通過T-SQL語句創(chuàng)建游標與實現(xiàn)數(shù)據(jù)庫加解密功能
這篇文章介紹了通過T-SQL語句創(chuàng)建游標與實現(xiàn)數(shù)據(jù)庫加解密功能的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-03-03
利用SQL Server觸發(fā)器實現(xiàn)表的歷史修改痕跡記錄
在很多應(yīng)用程序開發(fā)中,需要記錄某些數(shù)據(jù)表的歷史記錄或修改痕跡,以便日后出現(xiàn)數(shù)據(jù)錯誤時進行數(shù)據(jù)排查。這種業(yè)務(wù)需求,我們可以通過數(shù)據(jù)庫的觸發(fā)器來輕松實現(xiàn)歷史記錄功能2020-02-02
sql server 自定義分割月功能詳解及實現(xiàn)代碼
這篇文章主要介紹了sql server 自定義分割月功能詳解及實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10
Sql Server 2000刪除數(shù)據(jù)庫備份文件
Sql Server 2000刪除數(shù)據(jù)庫備份文件的語句。2009-09-09
基于Microsoft SQL Server實現(xiàn)編寫漢字轉(zhuǎn)拼音函數(shù)
在搜索應(yīng)用中,我們一般會提供一個搜索框,輸入關(guān)健字,點擊查詢按鈕以獲取結(jié)果數(shù)據(jù),大部分情況我們會提供模糊查詢的形式以在一個或多個字段進行搜索以獲取結(jié)果,本文給大家就介紹了基于Microsoft SQL Server實現(xiàn)編寫漢字轉(zhuǎn)拼音函數(shù),需要的朋友可以參考下2024-03-03

