關於數據庫主鍵ID的選擇

1、如何選擇

在mysql中,咱們要查詢一條或多條數據,都會經過索引來更快的查詢數據,一般每條數據都會有一個主鍵ID用來構建索引方便查詢。
因爲
那麼主鍵ID該選怎麼選呢?java

2、自增主鍵ID

自增主鍵ID一般都會選擇int類型或者long類型。mysql

它的優勢是:
簡單方便,有序遞增,方便排序和分頁等。算法

缺點:
1.隨着業務的增加,當id達到int最大值或者long最大值時,服務將不可用,存在上限問題。
2.簡單遞增容易被其餘人猜想利用,經過id數來判斷新增多少條數據或是用作他途。
3.根據業務須要分庫分表時,會有id重複等問題。sql

試用場景:比較適合數據量很少,併發量比較小的狀況下使用。數據庫

3、UUID

UUID是通用惟一識別碼(Universally Unique Identifier)的縮寫,開放軟件基金會(OSF)規範定義了包括網卡MAC地址、時間戳、名字空間(Namespace)、隨機或僞隨機數、時序等元素。利用這些元素來生成UUID。安全

UUID是由128位二進制組成,通常轉換成十六進制,而後用String表示。
java中自帶UUID類,有4種不一樣的UUID的生成策略:網絡

randomly : 基於隨機數生成UUID,因爲Java中的隨機數是僞隨機數,其重複的機率是能夠被計算出來的。
time-based : 基於時間的UUID,這個通常是經過當前時間,隨機數,和本地Mac地址來計算出來,自帶的JDK包並無這個算法的咱們在一些UUIDUtil中,好比咱們的log4j.core.util,會從新定義UUID的高位和低位。
DCE security : DCE安全的UUID。
name-based :基於名字的UUID,經過計算名字和名字空間的MD5來計算UUID。併發

UUID的優勢:
經過本地生成,沒有通過網絡I/O,性能較快
無序,沒法預測生成順序(也是缺點之一)。
不會出現重複dom

缺點:
使用字符串進行存儲,佔用必定的存儲空間,須要排序的時候會比較麻煩,查詢相對較慢分佈式

適用場景:能夠爲不須要擔憂過多的空間佔用的狀況下,以及不須要生成有遞增趨勢的數字的場景

4、雪花算法生成ID

該算法是推特開源的snowflake(雪花)算法,用來生成分佈式ID的。
其目的是生成一個64bit的整數:

圖片描述

1bit:通常是符號位,不作處理
41bit:從開始用的時間開始算,用來記錄時間戳,這裏能夠記錄69年。若是真用完了呢。。。那也是年輕人去解決的事了。。。
10bit:10bit用來記錄機器ID,總共能夠記錄1024臺機器,通常用前5位表明數據中心,後面5位是某個數據中心的機器ID
12bit:循環位,用來對同一個毫秒以內產生不一樣的ID,12位能夠最多記錄4095個,也就是在同一個機器同一毫秒最多記錄4095個,多餘的須要進行等待下毫秒。

優勢:
總體上按照時間自增排序,而且整個分佈式系統內不會產生ID碰撞(由數據中心ID和機器ID
做區分),而且效率較高,經測試,SnowFlake每秒可以產生26萬ID左右

缺點:
1.過度依賴機器時鐘,若是機器時鐘回撥,會致使重複ID生成
2.根據雪花算法,在單機上是絕對遞增的,可是因爲設計到分佈式環境,每臺機器上的時鐘不可能徹底同步,有時候會出現不是全局遞增的狀況(通常分佈式ID只要求趨勢遞增,並不會嚴格要求遞增。我以爲正常配置雪花算法的狀況下國內併發量使用雪花算法出問題的公司不會有太多。。)

適用場景:應用在分佈式系統中,適用於併發量大的場景。

5、結尾

根據自身系統服務的狀況來選擇生成的主鍵ID。上面三種咱們公司都有用到,看了看數據庫裏的表,感受頭有點大。。

相關文章
相關標籤/搜索