常玉慧
摘要:主鍵在數(shù)據(jù)庫(kù)中具有重要地位,其設(shè)計(jì)直接影響到數(shù)據(jù)庫(kù)系統(tǒng)的應(yīng)用和效能。該文從主鍵概念出發(fā),對(duì)現(xiàn)在常用的數(shù)據(jù)庫(kù)主鍵設(shè)計(jì)方法進(jìn)行了比較,提出了主鍵設(shè)計(jì)的相關(guān)原則。
關(guān)鍵詞:關(guān)系數(shù)據(jù)庫(kù);主鍵設(shè)計(jì)
中圖分類(lèi)號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2009)36-10176-02
Discussion on Principles for Database Primary Key Design
CHANG Yu-hui
(Jiangsu Technical Teachers College, Computer Engineering, Changzhou 203001, China)
Abstract: Primary keys are very important in databases, and .their design directly affects the application and performance of database systems. Starting from the concept of the primary key, the paper compares the commonly used design methods of the primary key, and proposes the relevant principles for primary key design.
Key words: Database; primary key
1 主鍵的概念及其設(shè)計(jì)主鍵的必要性
在我們進(jìn)行數(shù)據(jù)庫(kù)設(shè)計(jì)中,不可逃避的就是要定義數(shù)據(jù)庫(kù)表的主鍵,主鍵的設(shè)計(jì)對(duì)整個(gè)數(shù)據(jù)庫(kù)的設(shè)計(jì)影響很大,因此我們不得不要重視起來(lái)。那么我們首先來(lái)看看什么是數(shù)據(jù)庫(kù)的主鍵和與它密切相關(guān)的外鍵。
1.1 主鍵
能夠唯一表示數(shù)據(jù)表中的每個(gè)記錄的字段或者字段的組合就稱(chēng)為主鍵(主碼)。一旦確定為主鍵則該字段不可為空也不可以重復(fù)。一個(gè)主鍵是唯一識(shí)別一個(gè)表的每一記錄,但這只是其作用的一部分。主鍵的主要作用是將記錄和存放在其他表中的數(shù)據(jù)進(jìn)行關(guān)聯(lián)。在這一點(diǎn)上主鍵是不同表中各記錄之間的簡(jiǎn)單指針。所以主鍵的值對(duì)用戶(hù)而言是沒(méi)有什么意義并且和它要賦予的值也沒(méi)有什么特別的聯(lián)系。比如學(xué)生表中的學(xué)號(hào)就可以定義成該表的主鍵。
1.2 外鍵
外鍵的定義是相對(duì)于主鍵而言的若有兩個(gè)表A、B,key是A的主鍵而B(niǎo)中也有key字段則key就是表B的外鍵。比如另有一張成績(jī)表表中也出現(xiàn)了學(xué)生表中的對(duì)應(yīng)學(xué)號(hào)字段則相對(duì)于學(xué)生表學(xué)號(hào)就是成績(jī)表的外鍵。
1.3 設(shè)計(jì)主鍵的必要性
有些朋友可能不提倡數(shù)據(jù)庫(kù)表必須要主鍵,但在我的思考中,覺(jué)得每個(gè)表都應(yīng)該具有主鍵,不管是單主鍵還是雙主鍵,主鍵的存在就代表著表結(jié)構(gòu)的完整性,表的記錄必須得有唯一區(qū)分的字段,主鍵主要是用于其他表的外鍵關(guān)聯(lián),本記錄的修改與刪除,當(dāng)我們沒(méi)有主鍵時(shí),這些操作會(huì)變的非常麻煩。主鍵除了上述作用外常常與外鍵構(gòu)成參照完整性約束防止出現(xiàn)數(shù)據(jù)不一致。所以數(shù)據(jù)庫(kù)在設(shè)計(jì)時(shí)主鍵起到了很重要的作用。
2 主鍵設(shè)計(jì)的原則
大家都設(shè)計(jì)過(guò)數(shù)據(jù)庫(kù),也為表定義過(guò)主鍵,我想闡述的是,應(yīng)該如何正確的設(shè)計(jì)一個(gè)主鍵,在以往的一些資料中,都只是提了主鍵設(shè)計(jì)的方法而沒(méi)有提及到主鍵設(shè)計(jì)的原則。針對(duì)于此,我對(duì)幾種常用的設(shè)計(jì)主鍵的方法做了如下總結(jié):
2.1 是否要采用自動(dòng)遞增的方式
對(duì)于以前談到的主鍵,要求唯一性,因此大家都用自動(dòng)遞增的方式。這樣的方式是非常不可取的??赡苁菫榱朔奖悴迦胗涗洉r(shí),不必去人為創(chuàng)建主鍵值。以為這樣會(huì)方便,其實(shí)不是的。帶來(lái)的麻煩要遠(yuǎn)遠(yuǎn)勝于這種所謂的"方便"。第一,數(shù)據(jù)導(dǎo)入不方便,經(jīng)常會(huì)有從另一系統(tǒng)導(dǎo)入數(shù)據(jù)進(jìn)來(lái),自動(dòng)遞增的主鍵,將不允許原表中的ID被導(dǎo)入進(jìn)來(lái)。這會(huì)導(dǎo)致主鍵丟失。第二,對(duì)于象訂單這樣的有主外鍵的表來(lái)說(shuō),如果訂單的"主檔表"主鍵是自動(dòng)生成的,那么在保存一個(gè)訂單時(shí),會(huì)要求對(duì)主檔表與明細(xì)表同進(jìn)行事務(wù)保存,而此時(shí),先要生成一條訂單,然后取出這個(gè)訂單自動(dòng)生成的主鍵,然后再把此作為明細(xì)表的一個(gè)外鍵,進(jìn)行明細(xì)的保存。這過(guò)程中,將變的復(fù)雜而且不可行,事務(wù)將如何處理呢?訂單主檔表插入記錄后,要是明細(xì)保存時(shí)遇到錯(cuò)誤,主檔表記錄還要進(jìn)行刪除。繁瑣。插入成功以后,還要取出產(chǎn)生的最大值。這將是一個(gè)嚴(yán)重的浪費(fèi)。記錄多的話(huà)會(huì)影響速度,而且會(huì)存在并行插入。導(dǎo)致獲取的記錄可能是不正確的。因此在以上的嚴(yán)重問(wèn)題下,請(qǐng)不要采用自動(dòng)遞增方式。
2.2 是否要采用int型作為主鍵
以前大家都采用int型作為主鍵,導(dǎo)致主鍵的值都是數(shù)字。其實(shí)我們也明白。并不是只是數(shù)字的東西就是數(shù)字型的,比如電話(huà)號(hào)碼等。因此對(duì)于主鍵采用int型的優(yōu)勢(shì)是速度快插入查詢(xún)時(shí)都可能會(huì)比其他的方式快。但我這種快的效果也未必有多明顯比如以varchar(15)為例物理主鍵排序的數(shù)據(jù)會(huì)自動(dòng)以主鍵進(jìn)行物理數(shù)據(jù)排序。因此就算是字符型的數(shù)據(jù)在插入時(shí)也會(huì)插入到相應(yīng)的物理位置上也就是說(shuō)在插入時(shí)可能會(huì)影響一些速度。但在以后的查詢(xún)中速度影響不會(huì)太明顯。而我要說(shuō)的不采用int型作為主鍵不是說(shuō)里面不存數(shù)據(jù)。我還是建議大家在主鍵中存放數(shù)字這樣的排序比較要比夾雜字母的排序來(lái)的快之所以要采用字符型也是為以后的數(shù)據(jù)導(dǎo)入作準(zhǔn)備有一天會(huì)要求從其他表導(dǎo)入數(shù)據(jù)時(shí)可以在導(dǎo)入數(shù)據(jù)的主鍵上加一個(gè)特定字母來(lái)避免與原主鍵沖突。比如在導(dǎo)入數(shù)據(jù)的主鍵前加一個(gè)“N”字母。這也就不用擔(dān)心要求導(dǎo)入數(shù)據(jù)表中的主鍵是數(shù)字型還是字符型了。
2.3 是否采用編號(hào)來(lái)定義主鍵
主鍵設(shè)計(jì)有個(gè)原則就是主鍵不應(yīng)具有任何實(shí)際意義,這條其實(shí)是非常重要的。有人就是覺(jué)得編號(hào)本身是唯一的可以作為主鍵用但可能會(huì)為以后帶來(lái)麻煩。因?yàn)閹в袑?shí)際意義的字段還是存在被修改的可能性,而對(duì)于主鍵最大的忌諱就是修改主鍵,這可能會(huì)導(dǎo)致非常嚴(yán)重的不可估計(jì)的后果。比如學(xué)生編號(hào)平時(shí)以為永遠(yuǎn)不會(huì)修改但修改的可能還是會(huì)存在。
還有一種表面上是唯一的但實(shí)際上應(yīng)該是允許重復(fù)的。舉個(gè)例子,訂單編號(hào)應(yīng)該是唯一吧。邏輯上是的,可是會(huì)存在這樣的情況一張?jiān)瓉?lái)的訂單是因?yàn)槟硞€(gè)原因要求訂單作廢。那好給訂單的狀態(tài)標(biāo)識(shí)為"cancel"。然后允許再次錄入同樣編號(hào)的訂單。因此。對(duì)于這樣的情況下在雖然有效的訂單編號(hào)只有一個(gè)但在數(shù)據(jù)庫(kù)角度會(huì)允許編號(hào)重復(fù)。所以不管如何還是建議大家為表都建一個(gè)沒(méi)有任何意義的主鍵如ID。
2.4 是否要采用GUID作為主鍵
很多項(xiàng)目是多級(jí)建庫(kù)的,經(jīng)常需要數(shù)據(jù)導(dǎo)入、導(dǎo)出、合并很需要一套產(chǎn)生全局唯一主鍵的機(jī)制。一種方法是自己設(shè)計(jì)一套編碼規(guī)范(類(lèi)似于身份證、信用卡)最好有一個(gè)統(tǒng)一編碼服務(wù)器;第二種方法也是自己產(chǎn)生主鍵為每一個(gè)獨(dú)立的數(shù)據(jù)庫(kù)分配一個(gè)NameSpace產(chǎn)生主鍵時(shí)前面加上這個(gè)NameSpace;最后一種方法就是UUID我想重點(diǎn)討論一下后者。
UUID(Universally Unique Identifier)是通用惟一標(biāo)識(shí)符,是128位比特的數(shù)字,用來(lái)惟一地標(biāo)識(shí)因特網(wǎng)上的某些對(duì)象或者實(shí)體。UUID是是由開(kāi)放軟件基金會(huì)(OSF)作為分布式計(jì)算環(huán)境(DCE)的一部分而制定的標(biāo)準(zhǔn)。UUIDs的目的就是使分布式系統(tǒng)可以不需要重要的中央調(diào)合系統(tǒng)而能唯一地標(biāo)識(shí)信息。這樣,任何人能創(chuàng)造一個(gè)UUID和使用它來(lái)標(biāo)識(shí)一些東西,而且,你有足夠的信心來(lái)確定這個(gè)標(biāo)識(shí)是永遠(yuǎn)不會(huì)被任何人無(wú)意地使用在任何東西上。因此,信息加上了UUID標(biāo)簽就能合并到單個(gè)數(shù)據(jù)庫(kù)中而不用去解決命名沖突的問(wèn)題。這個(gè)標(biāo)準(zhǔn)的廣泛應(yīng)用在微軟的全球唯一標(biāo)識(shí)符(GUIDs)上,GUID實(shí)現(xiàn)了這個(gè)標(biāo)準(zhǔn)。
用GUID作主鍵有它的優(yōu)勢(shì)與不足。優(yōu)勢(shì)是GUID具有唯一性,在任何情況下,可以產(chǎn)生全球唯一的值。這是GUID最大的優(yōu)勢(shì),也方便數(shù)據(jù)導(dǎo)入,比如要求從另一個(gè)系統(tǒng)中把數(shù)據(jù)導(dǎo)入進(jìn)來(lái),那么不用擔(dān)心導(dǎo)入時(shí),會(huì)導(dǎo)致主鍵沖突。不足是GUID值太復(fù)雜、不易記憶,因?yàn)橛袝r(shí)難免我們會(huì)用記錄的方式來(lái)進(jìn)行記錄判斷。而且數(shù)據(jù)太長(zhǎng),影響數(shù)據(jù)庫(kù)效率。GUID的產(chǎn)生不是以一定的次序產(chǎn)生,對(duì)于按主鍵物理排序的數(shù)據(jù)庫(kù)來(lái)說(shuō),如果在記錄的前部插入一條記錄,可能會(huì)導(dǎo)致后面N次方的數(shù)據(jù)條數(shù)后移。這將導(dǎo)致數(shù)據(jù)插入效率。而且這個(gè)值是隨機(jī)、無(wú)順序的。GUID的值有16個(gè)字節(jié),與其它那些諸如4字節(jié)的整數(shù)相比要相對(duì)大一些。這意味著如果在數(shù)據(jù)庫(kù)中使用unique identifier鍵,可能會(huì)帶來(lái)兩方面的消極影響,一是存儲(chǔ)空間增大,二是索引時(shí)間較慢。因此GUID的采用應(yīng)該要慎重。
3 結(jié)束語(yǔ)
數(shù)據(jù)庫(kù)主鍵在數(shù)據(jù)庫(kù)中具有重要的地位。主鍵的設(shè)計(jì)直接影響到數(shù)據(jù)庫(kù)系統(tǒng)的應(yīng)用和效能。數(shù)據(jù)庫(kù)主鍵的設(shè)計(jì)并沒(méi)有定論,因此,我們?cè)谠O(shè)計(jì)主鍵時(shí),因根據(jù)具體應(yīng)用的需要,綜合考慮各方面的因素,考慮數(shù)據(jù)庫(kù)的規(guī)模,以及插入、刪除、檢索等操作的頻繁來(lái)選擇合適而快捷的數(shù)據(jù)庫(kù)主鍵設(shè)計(jì)方法,從而達(dá)到優(yōu)化數(shù)據(jù)庫(kù)主鍵的目的。
參考文獻(xiàn):
[1] 張?jiān)茲?商業(yè)智能的設(shè)計(jì)部署與實(shí)現(xiàn)[M].北京:電子工業(yè)出版社,2004.
[2] Lou Agosta.The Essential Guide to Data Warehouse [M].北京:人民郵電出版社,2000.11.
[3] 龔小勇.關(guān)系數(shù)據(jù)庫(kù)[M].北京:機(jī)械工業(yè)出版社,2004.
[4] 薩師煊,王珊.數(shù)據(jù)庫(kù)系統(tǒng)概述[M].北京:高等教育出版社,2002.