資料庫主鍵設計原則

2021-06-23 04:34:51 字數 2942 閱讀 3728

資料庫主鍵設計原則

或許大家都設計過資料庫,也為表定義過主鍵,今天我想闡述的是,應該如何正確的設計乙個主鍵,在以往的一些資料中,都沒有提及到主鍵設計的原則.

我為此總結了一下:

1.是否要採用guid作為主鍵

用guid作主鍵有它的優勢與不足.優勢是guid具有唯一性,在任何情況下,可以產生全球唯一的值.這是guid最大的優勢,也方便資料匯入,

比如要求從另乙個系統中把資料匯入進來,那麼,不用擔心,匯入時,會導致主鍵衝突.不足是guid值太複雜.不易記憶,

因為有時,難免我們會用記錄的方式,來進行記錄判斷.而且資料太長,影響資料庫效率.guid的產生不是以一定的次序產生,

對於按主鍵物理排序的資料庫來說,如果在記錄的前部插入一條記錄,可能會導致後面n次方的資料條數後移.這將導致資料插入效率.

因此guid的採用應該要慎重.

2.是否要採用自動遞增的方式

對於以前談到的主鍵,要求唯一性,因此大家都用自動遞增的方式.這樣的方式是非常不可取的.可能是為了方便插入記錄時,不必去人為建立主鍵值.

以為這樣會方便,其實不是的.帶來的麻煩要遠遠勝於這種所謂的"方便".第一:資料匯入不方便,經常會有從另一系統匯入資料進來,自動遞增的主鍵,

將不允許原表中的id被匯入進來.這會導致主鍵丟失.第二:對於象訂單這樣的有主外來鍵的表來說,如果訂單的"主檔表"主鍵是自動生成的.

那麼在儲存乙個訂單時,會要求對主檔表與明細表同進行事務儲存,而此時,先要生成一條訂單,然後取出這個訂單自動生成的主鍵,

然後再把此作為明細表的乙個外來鍵,進行明細的儲存.這過程中,將變以複雜而且不可行.事務如何處理.訂單主檔表插入記錄後,

要是明細儲存時遇到錯誤,主檔表記錄還要進行刪除.煩.插入成功以後,還要取出產生的最大值.這將是乙個嚴重的浪費.

記錄多的話會影響速度,而且會存在並行插入.導致獲取的記錄可能是不正確的. 因此在以上的嚴重問題下,請不要採用自動遞增方式.

3.是否要採用int型作為主鍵

以前大家都採用int型,都是出來主鍵都是數字導致的.其實我們也明白.並不是只是數字的東西就是數字型的.比如**號碼等.

因此對於主鍵,採用 int型的優勢是速度快,插入,查詢時都可能會比其他的方式快.但我這種快的效果也未必有多明顯,

比如以varchar(15)為例,物理主鍵排序的資料,會自動以主鍵進行物理資料排序.因此,就算是字元型的資料,在插入時也會插入到相應的物理位置上,

也就是說,在插入時可能會影響一些速度.但在以後的查詢中,速度影響不會太明顯.而我要說的,不採用int型作為主鍵,不是說,裡面不存資料.

我還是建議大家在主鍵中存放數字,這樣的排序比較要比夾雜字母的排序來的快,之所以要採用字元型,也是為以後的資料匯入作準備,

有一天,會要求從其他表匯入資料時,可以在匯入資料的主鍵上加乙個特定字母來避免與原主鍵衝突.比如在匯入資料的主鍵前加乙個"n"字母.

這也就不用擔心,要求匯入資料表中的主鍵是數字型還是字元型了.

4.是否採用編號來定義主鍵

這個問題是老生常談了.主鍵設計有個原則,就是主鍵不應具有任何實際意義.這條其實是非常重要,有人就是覺得編號本身是唯一的,

可以作為主鍵用,但可能會為以後帶來麻煩.因為帶有實際意義的字段,還是存在被修改的可能性.而對於主鍵最大的忌諱就是修改主鍵,

這可能會導致非常嚴重的不可估計的後果.比如學生編號,平時以為永遠不會修改,但修改的可能還是會存在.

還有一種,表面上是唯一的,但實際上應該是允許重複的.我舉個例子,訂單吧,訂單編號應該是唯一吧.是的.可是會存在這樣的情況,

一張原來的訂單是因為某個原因,要求訂單作廢.那好給訂單的狀態標識為"cancel".然後允許再次錄入同樣編號的訂單.

因此.對於這樣的情況下在,雖然有效的訂單編號只有乙個,但在資料庫角度會允許編號重複.

所以不管如何,還是建議大家為表都建乙個沒有任何意義的主鍵,如id.

因此,總結一下,我在設計主鍵,會採用字元型的.不採用自動遞增,在新增記錄時,系統生成主鍵值.一般為全數字進行存入,

至於主鍵值的生成規則,可以按需求進行規則定義.如果沒有特殊的要求,

只是為了保持唯一,可以定義乙個字段存放乙個數值.在生成時,自動加一.然後再存回去.這也比從乙個表中尋找最大值要來的快吧.

目前乙個比較好的主鍵是採用guid,當然我是推薦主鍵還是字元型的,但值由guid生成,guid是可以自動生成,也可以程式生成

,而且鍵值不可能重複,可以解決系統整合問題,幾個系統的guid值導到一起時,也不會發生重複,就算有「o」老資料也可以區分,而且效率很高,

在.net裡可以直接使用system.guid.newguid()進行生成,在sql裡也可以使用 newid()生成。

優點是:

同 identity 列相比,uniqueidentifier 列可以通過 newid() 函式提前得知新增加的行 id,為應用程式的後續處理提供了很大方便。

便於資料庫移植,其它資料庫中並不一定具有 identity 列,而 guid 列可以作為字元型列轉換到其它資料庫中,

同時將應用程式中產生的 guid 值存入資料庫,它不會對原有資料帶來影響。

便於資料庫初始化,如果應用程式要載入一些初始資料, identity 列的處理方式就比較麻煩,

而 uniqueidentifier 列則無需任何處理,直接用 t-sql 載入即可。

便於對某些物件或常量進行永久標識,如類的 classid,物件的例項標識,uddi 中的聯絡人、服務介面、tmodel標識定義等。

缺點是:

guid 值較長,不容易記憶和輸入,而且這個值是隨機、無順序的。

guid 的值有 16 個位元組,與其它那些諸如 4 位元組的整數相比要相對大一些。這意味著如果在資料庫中使用 uniqueidentifier 鍵,

可能會帶來兩方面的消極影響:儲存空間增大;索引時間較慢。

我也不是推薦guid最好,其實在不同的情況,我們都可以採用上面的某一種方式,思考了一些利與弊,也方便大家在進行設計時參考。

這些也只是我的一點思考而已,而且可能我知識面限制,會有一些誤論在裡面,希望大家有什麼想法歡迎討論。

資料庫主鍵設計原則

或許大家都設計過資料庫,也為表定義過主鍵,今天我想闡述的是,應該如何正確的設計乙個主鍵,在以往的一些資料中,都沒有提及到主鍵設計的原則.我為此總結了一下 1.是否要採用guid作為主鍵 用guid作主鍵有它的優勢與不足.優勢是guid具有唯一性,在任何情況下,可以產生全球唯一的值.這是guid最大的...

資料庫主鍵設計原則

資料庫主鍵設計原則 或許大家都設計過資料庫,也為表定義過主鍵,今天我想闡述的是,應該如何正確的設計乙個主鍵,在以往的一些資料中,都沒有提及到主鍵設計的原則.我為此總結了一下 1.是否要採用guid作為主鍵 用guid作主鍵有它的優勢與不足.優勢是guid具有唯一性,在任何情況下,可以產生全球唯一的值...

資料庫中表的主鍵設計原則

或許大家都設計過資料庫,也為表定義過主鍵,今天我想闡述的是,應該如何正確的設計乙個主鍵,在以往的一些資料中,都沒有提及到主鍵設計的原則.我為此總結了一下 1.是否要採用guid作為主鍵 用guid作主鍵有它的優勢與不足.優勢是guid具有唯一性,在任何情況下,可以產生全球唯一的值.這是guid最大的...