分佈式系統中咱們每每須要進行分庫分表,提高性能,這時候咱們就會須要一個高性能的全局惟一Id生成器,又稱發號器。mysql
UUID由MAC地址、時間戳、命名空間、隨機/僞隨機數、時序等元素構成,JAVA自帶,使用簡單,一樣的,它的缺點也很是的明顯。redis
MySQL tries to leave space so that future inserts do not incur un-necessary page splits (and thus higher IO cost). In an "ideal" world, MySQL tries to keep the index pages at 15/16-th full, but depending on insert order, this fill factor can be as low as 1/2算法
大部分狀況下,咱們使用的數據庫都是mysql,使用的mysql索引都是InnoDB,而InnoDB是主鍵構成的B+Tree(每一個節點攜帶數據),因此亂序插入時Innodb須要不停的申請新的page,而且進行tree的從新分佈,致使插入速度變慢,查詢也有約10%的性能損失和40~50%的空間浪費。sql
利用數據庫的自增,咱們也能夠方便的進行惟一Id生成,簡單方便,可是問題也很明顯,首先我插入了一條數據,還要再查詢一次才能夠知道id,其次簡單的自增很容易引起漏洞。若是咱們把它做爲全局惟一ID的話,在分庫分表的狀況下,還須要一個專門的數據庫表自增(相似redis),查出id,而後在分庫分表,性能不好。數據庫
利用incr咱們能夠很容易的實現id自增且redis是原子性的,不會重號。問題的仍是引入了組件,id的生成複雜度提升。分佈式
Zookeeper的話經過帶有編號的節點也能夠實現全局惟一id的生產,可是使用的比較少,一樣的,引入了組件,提升了系統複雜度。ide
SnowFlake算法生成64位的二進制正整數,而後轉換成10進制的數,性能很高,不依賴組件,性能好,適合生產使用。性能
學我者生,似我者死。-齊白石mysql索引
寫程序咱們也不須要依葫蘆畫瓢,能夠根據本身項目的需求,對64位二進制進行從新劃分,從新定義。this