在資料量不大的情況下,單庫單錶完全滿足現有業務,但是隨著資料日益增大,分庫分表是必然的操作,這時候繼續用資料庫的自增id無法滿足需求,因為假如有多張表都是存訂單的資訊,每個表都是自增的id,那就會出現重複的id號了,當然可以設定表的步長,比如表1的id從1開始,每隔兩步增長一次。表2的id從2開始,那麼他們的id就會是1,3,5,7,9…,2,4,6,8,10…,但是這樣後續的擴容也是很麻煩的事情,比如表的繼續增加咋辦,依然不是好的解決辦法。
如果要得到乙個全域性唯一的id,首先估計會想到使用uuid,生成方法很簡單:string uuid = uuid.randomuuid().tostring();得到的結果類似這樣:b8375e0f-4853-4f5c-9133-2ed64e7e7d87,這樣的字串用來做主鍵的話是不符合mysql的索引原則的,之前的文章有專門寫過mysql索引的原則,因為mysql在生成索引樹的時候是要計算左右子樹的大小的,這樣的id做主鍵會使mysql的儲存和查詢效率變得很低。
雪花演算法(snowflake)
public class snowflakeidworker
if (datacenterid > maxdatacenterid || datacenterid < 0)
this.workerid = workerid;
this.datacenterid = datacenterid;
} /**
* 獲得下乙個id (該方法是執行緒安全的)
* @return snowflakeid
*/public synchronized long nextid()
//如果是同一時間生成的,則進行毫秒內序列
if (lasttimestamp == timestamp)
} //時間戳改變,毫秒內序列重置
else
//上次生成id的時間截
lasttimestamp = timestamp;
//移位並通過或運算拼到一起組成64位的id
return ((timestamp - twepoch) << timestampleftshift) //
| (datacenterid << datacenteridshift) //
| (workerid << workeridshift) //
| sequence;
} /**
* 阻塞到下乙個毫秒,直到獲得新的時間戳
* @param lasttimestamp 上次生成id的時間截
* @return 當前時間戳
*/protected long tilnextmillis(long lasttimestamp)
return timestamp;
} /**
* 返回以毫秒為單位的當前時間
* @return 當前時間(毫秒)
*/protected long timegen()
/** 測試 */
public static void main(string args)
}
雪花演算法生成分布式ID
package top.sponger.common.util import lombok.data 描述 twitter的分布式自增id雪花演算法snowflake public class snowflake if machineid max machine num machineid 0 th...
分布式ID生成方案
系統唯一id是設計乙個系統的時候常常會遇到的問題,也常常為這個問題而糾結。生成id的方法有很多,適應不同的場景 需求以及效能要求。所以有些比較複雜的系統會有多個id生成的策略。1 全域性唯一性 不能出現重複的id號,既然是唯一標識,這是最基本的要求 2 粗略有序 如果在分布式環境中做到完全有序,需要...
分布式全域性ID之雪花演算法
public class idworker if datacenterid maxdatacenterid datacenterid 0 system.out.printf worker starting.timestamp left shift d,datacenter id bits d,wor...