天天看點

棄用資料庫自增ID,曝光一下我自己用到的解決方法 (轉發)

在平時的項目開發中,我相信有很大一批人都在用這個資料庫自增ID,用資料庫自增ID有利也有弊。

    優點:節省時間,根本不用考慮怎麼來辨別唯一記錄,寫程式也簡單了,資料庫幫我們維護着這一批ID号。

    缺點:for example, 在做分布式資料庫時,要求資料同步時,這種自增ID就會出現嚴重的問題,因為你無法用該ID來唯一辨別記錄。同時在資料庫做移植時,也會出現各種問題,總之,對此自增ID有依賴的情況,都有可能出現問題。我絕對相信園子裡有很一部分人都被這個“好用的東西” 曾經害慘過!

  

  我平時在開發項目的時候,一般都沒有用到資料庫的自增ID, 是以我想分享一下自己的解決方法。

  解決思路:

    

1:定義一張表,專門用來存放存所有需要唯一ID的表名稱以及該表目前所使用到的ID值。

2: 寫一個存儲過程,專門用來在上一步的表中取ID值。

  這個思路非常簡單,我不作解釋了,直接來看看我的實作方法:

棄用資料庫自增ID,曝光一下我自己用到的解決方法 (轉發)
棄用資料庫自增ID,曝光一下我自己用到的解決方法 (轉發)

代碼

第一步:建立表

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    

                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

        --set ouput value

    set @key_value=@key

    --commit tran

    commit tran

        if @@error>0

      rollback tran

end

對于在表中不存在記錄,直接傳回一個預設值為1的鍵值,同時插入該條記錄到table_key表中。而對于已存在的記錄,key值直接在原來的key基礎上加1.

    總結一下,這種方法非常簡單,我說一下它的優缺點。

    優點:

       1:ID值是可控的。使用者可以從指定段開始配置設定ID值,這對于在分布式資料要求同資料同步時,非常友善,很好地解決了ID重複的問題。

       2:在編寫程式中,ID值是可見的,比如在再插入關聯的記錄時,相比使用資料庫自增ID的情況下,這種方法不需要在插入一條資料庫記錄之後,再去得到自增ID值,然再再使用該ID的值來插入關聯的記錄。我們可以一次性使用事務來插入關聯記錄。

      3:對于需要批量插入資料時,我們可以改寫一下上面的存儲過程,傳回一個段的開始ID,然後更新表時需要注意,不是原來的簡單的遞增1,而是遞增你想要的插入多少條記錄的總數。

    缺點:

      1:效率問題,每次取ID值都需要調用存儲過程從資料庫中檢索一次。對于這種情況,我覺得效率不是很大問題,因為SQL server 會對我們經常調用的存儲過程有緩存,再一點,這個表的資料應該不會很大,最多上千條(一個項目中上千個表的情況應該不是很多吧)。是以檢索不是什麼問題,何況是根據表名來檢索(表名列已是主鍵)。

    2:并發問題。

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

      個人拙見!僅此而已!