編寫開源組件,天然一切都要採用最佳實踐。mysql
在第一步,設計數據表時就遇到了問題,過去的數據表中,一直採用AUTO_INCREMENT
的BigInt
做爲主鍵,也開始思考,BigInt
是否是最好的呢?git
注:微博、美團、微信、Twitter的業務都非自增,而是採用本身設計的分佈式ID
算法。github
又回到了經典的問題場景,數據庫設計,該用自增的Int
仍是UUID
?算法
MySQL
官方對UUID(Universally Unique IDentifier)
的解釋以下:sql
A UUID is designed as a number that is globally unique in space and time. Two calls to UUID() are expected to generate two different values, even if these calls are performed on two separate computers that are not connected to each other.
UUID
被設計爲一個在時間和空間內全局惟一的數字。UUID()
方法的屢次調用會生成不一樣的值,即使它們是在互不相連的獨立的計算機上執行的。數據庫
執行語句,生成一個UUID
。segmentfault
SELECT UUID() as UUID
UUID
的格式以下:安全
32
個16
進制數字,以-
做爲分隔符,格式爲8-4-4-4-12
,共計36
個字符。微信
853a7583-3bf9-11ea-8dc9-f48e38f0f826
$${16}^{32}\approx{3.4}\times{10}^{38}$$網絡
這個具體怎麼生成出來的就不研究了,瞭解全局惟一便可。
ps:segmentfault
的latex
公式還挺好使!
參考問題:The differences between INT and UUID in MySQL - StackOverflow
參考問題:UUID performance in MySQL - StackOverflow
參考文章:美團技術分享:深度解密美團的分佈式ID生成算法 - SegmentFault
若是選用了自增INT
做爲主鍵,會在特定數據庫與特定數據表內返回惟一的INT
值,可是並非全局惟一的,若是該數據庫被導入到其餘的數據庫,就會發生主鍵衝突。
UUID優勢
性能很是高:本地生成,無網絡消耗。
UUID缺點
不易於存儲:UUID
長度36
個字符,太長。
信息不安全:UUID
算法基於MAC
地址生成,可能會形成MAC
地址泄露。
MySQL
官方建議主鍵越短越好。且在InnoDB
引擎下,UUID
的無序性會嚴重影響性能。
看了好多關於二者對比的文章,大多數都是根本沒有通過實際業務考驗的紙上談兵,可是微信、美團的技術分享仍是很說明問題的。
精簡下來就是UUID
全局惟一,但其性能不適合大數據與高併發場景。
在數據庫層面,小業務,若是不考慮數據遷移與分佈式,INT
自增足夠了。大業務,分佈式、高併發、大數據,UUID
雖然能保證惟一,但性能不佳,仍需設計自定義的ID
算法。
發現美團的ID
算法是開源的,感謝美團:Leaf - Github