php與惟一ID生成的相關事宜

[原文地址:https://blog.ti-node.com/blog...]php

惟一ID的生成並非一件小事 , 想說愛它 , 也並非像簡單來一個uniqid()這樣一件容易的事 .node

爲何要惟一ID ?mysql

1 . 數據庫的自增ID在分庫的時候 , 會是一場災難 . 假設分兩個庫 , 由於每一個庫都會開始從1開始自增 , 屆時 , 系統中將會出現兩個id爲1的用戶 .nginx

2 . 自增id會暴露用戶量或者其餘業務量 .git

3 . 自增id會讓有心者經過API獲得任意用戶的信息資料 .github

解決方案呢 ?sql

1 . UUID , 全稱Universally Unique Identifier , 中文通用惟一標識符 . 這個是開放軟件基金會組織提出的一個標準 , 爲的就是解決分佈式環境下生成惟一標識符的問題 . UUID的長度是固定的32位 , 組織格式8-4-4-4-12 , 固然了在用的時候 , 中間的分隔符是要去掉的 . 這個貨有幾個問題不得不提 , 首先是字母數字混合 , 在一些傳統數據庫下 , 索引不太好作 , 不只索引體積大 , 查詢效率也差 . 其次是它自己也很是大 .數據庫

2 . MongoDB ObjectId , 格式模樣都很相似於UUID , 是Mongodb內置的一種數據類型 , 若是你在插入數據的時候不指定_id , 那麼Mongodb默認就會採用用這個貨才填充_id , 在Mongodb這種類kv性質的數據庫中 , 有着不錯的查詢效率 .flask

3 . 自建解決方案 , 爲了可以解決業務問題 , 不少公司都本身提出一些解決方案 , 這些方案無疑都要作到以下幾點 :服務器

  • 保證全局空間惟一性
  • 保證儘可能採起數字類型而非數字字母混合方式
  • 保證必定的時序行和含義
  • 保證必定的可反解性 , 經過反解的結果能夠知道該ID的相關信息

市面上有的幾種解決方案爲Twitter的snowflake , Flikr的數據庫自增方案 , Instagram的數據庫存儲過程方案 . 重點說下Twitter的snowflake解決方案原理 .

snowflask使用了64bit來表示一個id , Twitter的工程師們將它分紅了4個段 , 每段表示不一樣的含義 . 以下圖 :

前41bit段 , 是時間戳 , 單位會精確到毫秒級 . 因此該bit段能夠容納的時間容量爲 2^41 = 2.199x10^12 毫秒 , 也就是 2.199x10^9 秒 . 換算成年 , 就是大概爲69.7年 . 也就說 , 從1970年1月1日開始 , 可使用69.7年 , id產生機器的上限就到了 .

中10bit段 , 是機器ID , 最大能夠容納2^10=1024臺機器 . 你能夠部署1一臺以上的機器 , 給每一個機器配置一個不同凡響的獨立的id號 , 好比從1號開始 , 最多能夠部署到1024號機器 . 而後機器集羣最前面擋一臺nginx之類的服務器作代理 , 就能夠完成一個不錯的id發號集羣了 .

後12bit段 , 是自增序列( 你能夠等同爲mysql的自增id ) , 它表示的1毫秒內的自增序列 . 也就是說從0毫秒開始一直到1毫秒結束這段時間內自增 . 也就說1毫秒內最多產生2^12=4096個序列 , 也就是說同一臺機器上同一毫秒內最多產生4096個序列 , 若是超過了該數字 , 那就等待下一毫秒產生新的id .

TIPS : 順帶提一下 , php的uniqid()函數存在很大的風險 , 它生成的id並不能像它的名字那樣作到uniqid , 重複機率略高 . 詳情查看該函數的手冊頁評論 . 點擊這裏

TIPS : 推薦一個基於snowflake的php id產生器 : donkeyid生成器

相關文章
相關標籤/搜索