當咱們須要在多個數據庫間進行數據的複製自動增加型字段可能形成數據合併時的主鍵衝突。設想一個數據庫中的Order表向另外一個庫中的Order表複製數據庫時,OrderID到底該不應自動增加呢?html
數據庫自增加ID和無序的UUID方案的不足之處:算法
1)、採用數據庫自增序列:數據遷移合併等比較麻煩。mongodb
2)、UUID隨機數:採用無心義字符串,沒有排序UUID使用字符串形式存儲,數據量大時查詢效率比較低。(主要是索引查詢銷量不是最高的)數據庫
若是非要使用非自主增加列做爲主鍵的話(分佈式系統分庫分表中),推使用有序UUID和有序的整長的Rowid(雪花算法snowflake和MongoDB之ObjectId)。微信
參考資料:爲何要使用自增ID做爲主鍵 - Mr-blue - 博客園
https://www.cnblogs.com/lanqi/p/10185172.html併發
惟一ID能夠標識數據的惟一性,在分佈式系統中生成惟一ID的方案有不少,常見的方式大概有如下三種:app
2.一、依賴數據庫,使用SQL SERVER無序UUID和有序UUID。dom
1)、無序UUID:分佈式
SELECT newid() --生成36位的GUIDide
SELECT REPLACE(newid(), '-', '') -- 生成32 位的GUID
2)、有序UUID:
SQLServer 2005已經解決了這個問題,使用的是NEWSEQUENTIALID()
create table jobs
(
id UNIQUEIDENTIFIER ROWGUIDCOL PRIMARY KEY NOT NULL
CONSTRAINT [DF_jobs_id] DEFAULT (NEWSEQUENTIALID()),
account varchar(64) not null,
password varchar(64) not null
)
go
insert jobs (account,password) values ('tudou','123')
insert jobs (account,password) values ('ntudou','123')
insert jobs (account,password) values ('atudou','123')
insert jobs (account,password) values ('btudou','123')
insert jobs (account,password) values ('ctudou','123')
select * from jobs
參考資料:
SQL Server 的 主鍵 解決方案 NEWID() , 自增ID - 王佔波 - 博客園 https://www.cnblogs.com/wangzhanbo/articles/8807125.html
2.二、無序隨機UUID和有序UUID。
1)、無序UUID:
string guid = Guid.NewGuid().ToString();
string guid = Guid.NewGuid().ToString("N");
缺點:索引性能差。
2)、有序UUID:
https://www.cnblogs.com/lovewl2/p/10334987.html
https://www.cnblogs.com/shiningrise/p/5690016.html
惟一ID劃分須要根據單體應用仍是分佈式應用來進行區分。特別是在分佈式系統中,有一些須要使用全局惟一ID的場景,這種時候爲了防止ID衝突可使用36位的UUID,可是UUID有一些缺點,首先他相對比較長,另外UUID通常是無序的。有些時候咱們但願能使用一種簡單一些的ID,而且但願ID可以按照時間有序生成。
一、基於時間戳+隨機數方式來生成惟一ID
基於時間戳:DateTime.Now.ToString("yyyyMMddHHmmssfffffff")—這種狀況很容易出現重複的編號。
基於時間戳+隨機數:DateTime.Now.ToString("yyyyMMddHHmmssfffffff")+Random隨機數。
這種方式比較適合針對單體應用併發不高的業務系統,生成方式並非嚴格意義上的惟一ID。
二、C#仿造Snowflake雪花算法設計
有這麼一種說法,天然界中並不存在兩片徹底同樣的雪花的。每一片雪花都擁有本身漂亮獨特的形狀、獨一無二。雪花算法也表示生成的ID如雪花般獨一無二。而twitter的snowflake解決了這種需求。
snowflake是twitter開源的分佈式ID生成算法,其核心思想是:一個long型的ID,使用其中41bit做爲毫秒數,10bit做爲機器編號,12bit做爲毫秒內序列號。這個算法單機每秒內理論上最多能夠生成1000*(2^12),也就是400W的ID,徹底能知足業務的需求。關於雪花算法的組成部分:
雪花算法會生成一個64位的二進制數據,爲一個Long型。(轉換成字符串後長度最多19位) ,其基本結構:
第一位:爲未使用
第二部分:41位爲毫秒級時間(41位的長度可使用69年)
第三部分:5位datacenterId和5位workerId(10位的長度最多支持部署1024個節點)
第四部分:最後12位是毫秒內的計數(12位的計數順序號支持每一個節點每毫秒產生4096個ID序號)
snowflake生成的ID總體上按照時間自增排序,而且整個分佈式系統內不會產生ID碰撞(由datacenter和workerId做區分),而且效率較高。經測試snowflake每秒可以產生26萬個ID。
C# 分佈式自增ID算法snowflake(雪花算法) - 五維思考 - 博客園
https://www.cnblogs.com/zhaoshujie/p/12010052.html
三、C#仿造mongodb的分佈式主鍵ObjectId設計
MongoDB中_id(ObjectId)組成的12個字節按照以下方式生成
前四位是時間戳,能夠提供秒級別的惟一性。
接下來三位是所在主機的惟一標識符,一般是機器主機名的散列值。
接下來兩位是產生 ObjectId 的 PID,確保同一臺機器上併發產生的 ObjectId 是惟一的。
前九位保證了同一秒鐘不一樣機器的不一樣進程產生的 ObjectId 時惟一的。
最後三位是自增計數器,確保相同進程同一秒鐘產生的 ObjectId 是惟一的。