最近在做數據庫設計的時候(以MySQL為主),遇到不少困惑,因為之前做數據庫表設計,基本上主鍵都是使用自增的形式,最近因為這種做法,被領導指出存在一些不足,於是我想搞明白哪里不足。
一、MySQL為什么建議使用自增?
通過網上查閱資料,得出一個這樣的結論:
表的主鍵一般都要使用自增 id,不建議使用業務id ,是因為使用自增id可以避免頁分裂。
按照我過去的實踐:
選擇使用自增可以避免很多麻煩,主要體現是數據的唯一性(從1到xxx,肯定不會重復的)。
1.什么是頁分裂?
這塊我沒看太明白,我主要參考如下鏈接:
一看就懂的:MySQL數據頁以及頁分裂機制
二、UUID作為主鍵的優劣勢是什么?以及它的應用場景是什么?
1.UUID和自增int型作為主鍵的比較,有哪些優勢和劣勢?
(1)優勢
- UUID值在不同的表、數據庫、甚至是服務器中都是全局唯一的,所以你可以合並來自不同數據庫,甚至是不同服務器上不同數據庫上的數據行;
- UUID值不會在URL中暴露你的數據信息。例如,一個客戶可以通過 id10來訪問他的賬號地址 http://www.example.com/c/10/ ,他可以很輕松地猜到會有 id 11, 12等等的客戶,這可能被拖庫,或被別人猜到你的用戶量;
- UUID值生成的時候不需要查一遍數據庫,並且它還簡化了應用層的邏輯。例如,當你要給父表和子表插入數據時,一般你要先把數據插到父表里,然后才能插到子表里。但是如果你用UUID的話,你可以直接生成父表的主鍵,然后在一個事務里同時把數據插到父表和子表里。
專業名詞解釋
拖庫:指黑客通過各種社工手段、技術手段將數據庫中敏感信息非法獲取,一般這些敏感信息包括用戶的賬號信息如用戶名、密碼;身份信息如真實姓名、證件號碼;通訊信息如電子郵箱、電話、住址等。
(2)劣勢
- 存儲UUID值(16字節)需要的存儲空間比INT型(4字節)甚至是 BIGINT型(8字節)都要大;
- 調試起來會更難一些,你可以想象一下平時你只需要 WHERE id = 10 現在你要寫 WHERE id = ‘df3b7cb7-6a95-11e7-8846-b05adad3f0ae’;
- UUID 值通常會因為它的大小和未被排序的問題導致性能問題。
2.哪些應用場景應該使用UUID作為主鍵?
簡要概括UUID的適用場景:主要適合用在大型項目微服務架構中,保證全局ID唯一性(大型項目微服務架構集成各式各樣的子系統,避免ID沖突)。
起初我在數據表設計的時候就與項目經理爭論過,挺類似這個鏈接的對話:UUID與數字ID的區別與適用場景
三、什么是聯合主鍵?聯合主鍵的適用場景又是什么?
1.什么是聯合主鍵
指用2個或者是2個以上的字段組成的主鍵,用這個主鍵包含的字段作為主鍵,這個組合在數據表中是唯一,且附加上了主鍵索引。
2.聯合主鍵的適用場景是什么?
我能想到一個用戶信息,針對某個一個區域如果用用戶ID或用戶ID+用戶姓名作為主鍵,難以保持數據的唯一性,因為這一個地區不僅僅是有一個小馬哥,可能有七八個人,如此,前面提到的用戶ID或用戶ID+用戶姓名顯然是行不通的,這時可以把身份證加入主鍵,變成了用戶ID+用戶姓名+身份證(形成了一個聯合主鍵),這樣一來該用戶數據的唯一性得到了驗證。當然了,聯合主鍵的場景不僅僅是這個,關鍵看業務場景。
四、數據表設計心得分享
從外包公司->創業公司->教育公司->現在所在公司,回過頭來看過去我的數據表設計方面,存在的一個最大不足,即着重考慮技術實現難易層面,而輕視業務場景適用性、擴展性、穩定性等。