多台伺服器如何生成全局唯一id
『壹』 如何在高並發分布式系統中生成全局唯一id
我了解的方案如下…………………………………………………………………… 1、 使用資料庫自增Id 優勢:編碼簡單,無需考慮記錄唯一標識的問題。 缺陷: 1) 在大表做水平分表時,就不能使用自增Id,因為Insert的記錄插入到哪個分表依分表規則判定決定,若是自增Id,各個分表中Id就會重復,在做查詢、刪除時就會有異常。 2) 在對表進行高並發單記錄插入時需要加入事物機制,否則會出現Id重復的問題。 3) 在業務上操作父、子表(即關聯表)插入時,需要在插入資料庫之前獲取max(id)用於標識父表和子表關系,若存在並發獲取max(id)的情況,max(id)會同時被別的線程獲取到。 4) 等等。 結論:適合小應用,無需分表,沒有高並發性能要求。 2、 單獨開一個資料庫,獲取全局唯一的自增序列號或各表的MaxId
『貳』 如何在高並發分布式系統中生成全局唯一Id
1、 使用資料庫自增Id
優勢:編碼簡單,無需考慮記錄唯一標識的問題。
缺陷:
1) 在大表做水平分表時,就不能使用自增Id,因為Insert的記錄插入到哪個分表依分表規則判定決定,若是自增Id,各個分表中Id就會重復,在做查詢、刪除時就會有異常。
2) 在對表進行高並發單記錄插入時需要加入事物機制,否則會出現Id重復的問題。
3) 在業務上操作父、子表(即關聯表)插入時,需要在插入資料庫之前獲取max(id)用於標識父表和子表關系,若存在並發獲取max(id)的情況,max(id)會同時被別的線程獲取到。
4) 等等。
結論:適合小應用,無需分表,沒有高並發性能要求。
2、 單獨開一個資料庫,獲取全局唯一的自增序列號或各表的MaxId
1) 使用自增序列號表
專門一個資料庫,生成序列號。開啟事物,每次操作插入時,先將數據插入到序列表並返回自增序列號用於做為唯一Id進行業務數據插入。
注意:需要定期清理序列表的數據以保證獲取序列號的效率;插入序列表記錄時要開啟事物。
使用此方案的問題是:每次的查詢序列號是一個性能損耗;如果這個序列號列暴了,那就杯具了,你不知道哪個表使用了哪個序列,所以就必須換另一種唯一Id方式如GUID。
2) 使用MaxId表存儲各表的MaxId值
專門一個資料庫,記錄各個表的MaxId值,建一個存儲過程來取Id,邏輯大致為:開啟事物,對於在表中不存在記錄,直接返回一個默認值為1的鍵值,同時插入該條記錄到table_key表中。而對於已存在的記錄,key值直接在原來的key基礎上加1更新到MaxId表中並返回key。
使用此方案的問題是:每次的查詢MaxId是一個性能損耗;不過不會像自增序列表那麼容易列暴掉,因為是擺表進行劃分的。
詳細可參考:《使用MaxId表存儲各表的MaxId值,以獲取全局唯一Id》
我截取此文中的sql語法如下:
第一步:創建表
create table table_key
(
table_name varchar(50)not null primary key,
key_value int not null
)
第二步:創建存儲過程來取自增ID
create procere up_get_table_key
(
@table_name varchar(50),
@key_value int output
)
as
begin
begin tran
declare @key int
--initialize the key with 1
set @key=1
--whether the specified table is exist
if not exists(selecttable_name from table_key wheretable_name=@table_name)
begin
insert into table_keyvalues(@table_name,@key) --default key vlaue:1
end
-- step increase
else
begin
select @key=key_valuefrom table_key with (nolock) where table_name=@table_name
set @key=@key+1
--update the key value by table name
update table_key setkey_value=@key where table_name=@table_name
end
--set ouput value
set @key_value=@key
--commit tran
commit tran
if @@error>0
rollback tran
end
轉載僅供參考,版權屬於原作者。
『叄』 如何在高並發分布式系統中生成全局唯一Id
1、 使用資料庫自增Id
優勢:編碼簡單,無需考慮記錄唯一標識的問題。
缺陷:
1) 在大表做水平分表時,就不能使用自增Id,因為Insert的記錄插入到哪個分表依分表規則判定決定,若是自增Id,各個分表中Id就會重復,在做查詢、刪除時就會有異常。
2) 在對表進行高並發單記錄插入時需要加入事物機制,否則會出現Id重復的問題。
3) 在業務上操作父、子表(即關聯表)插入時,需要在插入資料庫之前獲取max(id)用於標識父表和子表關系,若存在並發獲取max(id)的情況,max(id)會同時被別的線程獲取到。
4) 等等。
結論:適合小應用,無需分表,沒有高並發性能要求。
2、 單獨開一個資料庫,獲取全局唯一的自增序列號或各表的MaxId
1) 使用自增序列號表
專門一個資料庫,生成序列號。開啟事物,每次操作插入時,先將數據插入到序列表並返回自增序列號用於做為唯一Id進行業務數據插入。
注意:需要定期清理序列表的數據以保證獲取序列號的效率;插入序列表記錄時要開啟事物。
使用此方案的問題是:每次的查詢序列號是一個性能損耗;如果這個序列號列暴了,那就杯具了,你不知道哪個表使用了哪個序列,所以就必須換另一種唯一Id方式如GUID。
2) 使用MaxId表存儲各表的MaxId值
專門一個資料庫,記錄各個表的MaxId值,建一個存儲過程來取Id,邏輯大致為:開啟事物,對於在表中不存在記錄,直接返回一個默認值為1的鍵值,同時插入該條記錄到table_key表中。而對於已存在的記錄,key值直接在原來的key基礎上加1更新到MaxId表中並返回key。
使用此方案的問題是:每次的查詢MaxId是一個性能損耗;不過不會像自增序列表那麼容易列暴掉,因為是擺表進行劃分的。
『肆』 如何在高並發分布式系統中生成全局唯一Id
c# 中的 Guid 就是唯一的,它保證對在同一時空中的所有機器都是唯一的. 據我所知,它也會產生碰撞,但是概率極小,完全可以不用理會的小。 可以用現有的支持原子操作的分布式資料庫, 例:Redis 很多網站用Redis 的原子性來生成唯一標識符 我們可以用本機的Mac地址,硬碟序列號,本地最大標識符來拼接出唯一。 Mac 可被修改,硬碟序列號也有可能不唯一,但是這三樣拼接在一起,碰撞的概率很小的 Md5 也會碰撞,不是么?
『伍』 分布式系統中,怎麼樣生成全局唯一的 ID
一種是分區段,例如,聯通手機什麼開頭,網通... 一種是設一個全局唯一伺服器負責這件事 誰有好主意,實際中用過,繼續添加
『陸』 如何在高並發分布式系統中生成全局唯一Id
我了解的方案如下……………………………………………………………………1、使用資料庫自增Id優勢:編碼簡單,無需考慮記錄唯一標識的問題。缺陷:1)在大表做水平分表時,就不能使用自增Id,因為Insert的記錄插入到哪個分表依分表規則判定決定,若是自增Id,各個分表中Id就會重復,在做查詢、刪除時就會有異常。2)在對表進行高並發單記錄插入時需要加入事物機制,否則會出現Id重復的問題。3)在業務上操作父、子表(即關聯表)插入時,需要在插入資料庫之前獲取max(id)用於標識父表和子表關系,若存在並發獲取max(id)的情況,max(id)會同時被別的線程獲取到。4)等等。結論:適合小應用,無需分表,沒有高並發性能要求。2、單獨開一個資料庫,獲取全局唯一的自增序列號或各表的MaxId
『柒』 如何在高並發分布式系統中生成全局唯一Id
一種是分區段,例如,聯通手機什麼開頭,網通...
一種是設一個全局唯一伺服器負責這件事
誰有好主意,實際中用過,繼續添加