昨日一個行內兄弟由於工作調動要派到某二線城市工作,雖然有高額工資和補助的誘惑但也難以釋懷離京蛋蛋的憂桑,約好晚上到老聚點道個別、主要是聊(chui)聊(chui)前(niu)程(bi),幾瓶奪命大綠棒子下肚,這貨問起我現在項目的情況(操蛋的技術控!),我簡單的說了一下架子和數據庫,果然在數據庫主鍵上出現了分歧,在他心里主鍵就是應該是妥妥的自增整型,對於我的GUID無法容忍,並指出GUID不連續、效率低下、blablabla,最后我說了一下我的解決方案總算得到了一定程度的肯定吧。。。
對於程序猿來說,數據庫設計是永恆的話題,而主鍵作為數據庫的重要元素是卻並未得到應有的重視。本文僅對自增整型和GUID做簡單對比,其他復合式、時間序列式等形式的主鍵暫不考慮。
主鍵的定義(From 百度知道)
主鍵:表中經常有一個列或列的組合,其值能唯一地標識表中的每一行。這樣的一列或多列稱為表的主鍵,通過它可強制表的實體完整性。當創建或更改表時可通過定義 PRIMARY KEY 約束來創建主鍵。一個表只能有一個 PRIMARY KEY 約束,而且 PRIMARY KEY 約束中的列不能接受空值。由於 PRIMARY KEY 約束確保唯一數據,所以經常用來定義標識列。
對自增量主鍵和GUID主鍵進行優劣對比(歡迎補充)
自增量主鍵
優勢:
數據庫自動生成,無需在業務中做任何管理
節省內存空間
數據寫入和檢索時效率較高
劣勢:
數據合並、遷移時易出現問題,這一點的重要性因具體項目而定。
GUID主鍵
優勢:
能在業務層就知道目標ID,而不是數據提交給數據庫系統后才確定。
在分表時好處明顯。
在數據庫合並、遷移等方面十分方便。
劣勢:
占用存儲空間稍大(對於當前硬件及RDBS情況幾乎可以忽略)
生成無序,檢索數據時較自增整型主鍵效率嚴重下降(通過其他方式解決)
由於我的項目可能會經常性升級並且對數據持久性要求較高,果斷選擇GUID作為數據主鍵,當然隨之而來的就是對檢索效率的懷疑。
其實GUID主鍵檢索效率低下的真正原因是聚合索引,當創建一個數據表時,系統會自動在主鍵上創建聚集索引,根據聚集索引的實現原理,無序的GUID無法發揮出聚集索引的作用,並且GUID做聚集索引可能還會引起葉分裂問題,嚴重杜絕把聚集索引建在GUID上!
也許你會考慮是否有有序的GUID?答案是肯定的!C#中內置了有序GUID的生成方法,但是只能在聯網的情況下保證全球唯一,並且如果遇到服務器重啟、系統重啟等情況生成的GUID將無法與重啟前的GUID保持正常順序。
針對聚集索引這里我做了一些小的改動,首先我將GUID主鍵的主鍵約束移除,並設置不可空+唯一性約束,出於歸檔考慮我的每張表中都會有【數據產生時間】列,將原屬於主鍵的聚集索引添加到該類上,保障了聚集索引的正常工作。
由於暫時項目進度太緊,沒有做測試數據,理論上還算可行吧,以后有時間再補。。