棄用數據庫自增ID,曝光一下我本身用到的解決方法

  在平時的項目開發中,我相信有很大一批人都在用這個數據庫自增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:併發問題。

不少人有提到!不過凡事都是一把雙刃劍,這就比如作優化,要麼以時間換空間,要麼以空間換時間,這個世界上根本不存十全十美的事物!

我的拙見!僅此而已!

相關文章
相關標籤/搜索