資料表設計之主鍵自增、UUID或聯合主鍵

挑戰者V發表於2021-04-05

最近在做資料庫設計的時候(以MySQL為主),遇到不少困惑,因為之前做資料庫表設計,基本上主鍵都是使用自增的形式,最近因為這種做法,被領導指出存在一些不足,於是我想搞明白哪裡不足。

一、MySQL為什麼建議使用自增?

通過網上查閱資料,得出一個這樣的結論:
表的主鍵一般都要使用自增 id,不建議使用業務id ,是因為使用自增id可以避免頁分裂。

按照我過去的實踐:
選擇使用自增可以避免很多麻煩,主要體現是資料的唯一性(從1到xxx,肯定不會重複的)。

1.什麼是頁分裂?

這塊我沒看太明白,我主要參考如下連結:
一看就懂的:MySQL資料頁以及頁分裂機制

為什麼?mysql不推薦使用uuid或者雪花id作為主鍵?

二、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 值通常會因為它的大小和未被排序的問題導致效能問題。

參考連結:
MySQL主鍵應該用UUID還是INT型別

一分鐘讓你瞭解拖庫、洗庫和撞庫

2.哪些應用場景應該使用UUID作為主鍵?

簡要概括UUID的適用場景:主要適合用在大型專案微服務架構中,保證全域性ID唯一性(大型專案微服務架構整合各式各樣的子系統,避免ID衝突)。

起初我在資料表設計的時候就與專案經理爭論過,挺類似這個連結的對話:UUID與數字ID的區別與適用場景

三、什麼是聯合主鍵?聯合主鍵的適用場景又是什麼?

1.什麼是聯合主鍵

指用2個或者是2個以上的欄位組成的主鍵,用這個主鍵包含的欄位作為主鍵,這個組合在資料表中是唯一,且附加上了主鍵索引。

2.聯合主鍵的適用場景是什麼?

我能想到一個使用者資訊,針對某個一個區域如果用使用者ID或使用者ID+使用者姓名作為主鍵,難以保持資料的唯一性,因為這一個地區不僅僅是有一個小馬哥,可能有七八個人,如此,前面提到的使用者ID或使用者ID+使用者姓名顯然是行不通的,這時可以把身份證加入主鍵,變成了使用者ID+使用者姓名+身份證(形成了一個聯合主鍵),這樣一來該使用者資料的唯一性得到了驗證。當然了,聯合主鍵的場景不僅僅是這個,關鍵看業務場景。

四、資料表設計心得分享

從外包公司->創業公司->教育公司->現在所在公司,回過頭來看過去我的資料表設計方面,存在的一個最大不足,即著重考慮技術實現難易層面,而輕視業務場景適用性、擴充套件性、穩定性等。

相關文章