在平時的項目開發中,我相信有很大一批人都在用這個數據庫自增ID,用數據庫自增ID有利也有弊。數據庫
優勢:節省時間,根本不用考慮怎麼來標識惟一記錄,寫程序也簡單了,數據庫幫咱們維護着這一批ID號。緩存
缺點:for example, 在作分佈式數據庫時,要求數據同步時,這種自增ID就會出現嚴重的問題,由於你沒法用該ID來惟一標識記錄。同時在數據庫作移植時,也會出現各類問題,總之,對此自增ID有依賴的狀況,都有可能出現問題。我絕對相信園子裏有很一部分人都被這個「好用的東西」 曾經害慘過!併發
我平時在開發項目的時候,通常都沒有用到數據庫的自增ID, 因此我想分享一下本身的解決方法。分佈式
解決思路:優化
1:定義一張表,專門用來存放存全部須要惟一ID的表名稱以及該表當前所使用到的ID值。 2: 寫一個存儲過程,專門用來在上一步的表中取ID值。
這個思路很是簡單,我不做解釋了,直接來看看個人實現方法:code
第一步:建立表 create table table_key ( table_name varchar(50) not null primary key, key_value int not null ) 第二步:建立存儲過程來取自增ID create procedure 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(select table_name from table_key where table_name=@table_name) begin insert into table_key values(@table_name,@key) --default key vlaue:1 end -- step increase else begin select @key=key_value from table_key with (nolock) where table_name=@table_name set @key=@key+1 --update the key value by table name update table_key set key_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
對於在表中不存在記錄,直接返回一個默認值爲1的鍵值,同時插入該條記錄到table_key表中。而對於已存在的記錄,key值直接在原來的key基礎上加1.server
總結一下,這種方法很是簡單,我說一下它的優缺點。事務
優勢:ci
1:ID值是可控的。用戶能夠從指定段開始分配ID值,這對於在分佈式數據要求同數據同步時,很是方便,很好 地解決了ID重複的問題。開發
2:在編寫程序中,ID值是可見的,好比在再插入關聯的記錄時,相比使用數據庫自增ID的狀況下,這種方法不須要在插入一條數據庫記錄以後,再去獲得自增ID值,然再再使用該ID的值來插入關聯的記錄。咱們能夠一次性使用事務來插入關聯記錄。
3:對於須要批量插入數據時,咱們能夠改寫一下上面的存儲過程,返回一個段的開始ID,而後更新表時須要注意,不是原來的簡單的遞增1,而是遞增你想要的插入多少條記錄的總數。
缺點:
1:效率問題,每次取ID值都須要調用存儲過程從數據庫中檢索一次。對於這種狀況,我以爲效率不是很大問題,由於SQL server 會對咱們常常調用的存儲過程有緩存,再一點,這個表的數據應該不會很大,最多上千條(一個項目中上千個表的狀況應該不是不少吧)。因此檢索不是什麼問題,況且是根據表名來檢索(表名列已經是主鍵)。
2:併發問題。
不少人有提到!不過凡事都是一把雙刃劍,這就比如作優化,要麼以時間換空間,要麼以空間換時間,這個世界上根本不存十全十美的事物!
我的拙見!僅此而已!