淺談如何屏蔽數據庫中自增ID功能
在平時的項目開發中,我相信有很大一批人都在用這個數據庫自增ID,用數據庫自增ID有利也有弊。
優點:節省時間,根本不用考慮怎么來標識***記錄,寫程序也簡單了,數據庫幫我們維護著這一批ID號。
缺點:for example, 在做分布式數據庫時,要求數據同步時,這種自增ID就會出現嚴重的問題,因為你無法用該ID來***標識記錄。同時在數據庫做移植時,也會出現各種問題,總之,對此自增ID有依賴的情況,都有可能出現問題。我絕對相信園子里有很一部分人都被這個“好用的東西” 曾經害慘過!
我平時在開發項目的時候,一般都沒有用到數據庫的自增ID, 所以我想分享一下自己的解決方法。
解決思路
1:定義一張表,專門用來存放存所有需要***ID的表名稱以及該表當前所使用到的ID值。
2: 寫一個存儲過程,專門用來在上一步的表中取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
- 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.
總結一下,這種方法非常簡單,我說一下它的優缺點。
優點:
1:ID值是可控的。用戶可以從指定段開始分配ID值,這對于在分布式數據要求同數據同步時,非常方便,很好地解決了ID重復的問題。
2:在編寫程序中,ID值是可見的,比如在再插入關聯的記錄時,相比使用數據庫自增ID的情況下,這種方法不需要在插入一條數據庫記錄之后,再去得到自增ID值,然再再使用該ID的值來插入關聯的記錄。我們可以一次性使用事務來插入關聯記錄。
3:對于需要批量插入數據時,我們可以改寫一下上面的存儲過程,返回一個段的開始ID,然后更新表時需要注意,不是原來的簡單的遞增1,而是遞增你想要的插入多少條記錄的總數。
缺點:
1:效率問題,每次取ID值都需要調用存儲過程從數據庫中檢索一次。對于這種情況,我覺得效率不是很大問題,因為SQL server 會對我們經常調用的存儲過程有緩存,再一點,這個表的數據應該不會很大,最多上千條(一個項目中上千個表的情況應該不是很多吧)。所以檢索不是什么問題,何況是根據表名來檢索(表名列已是主鍵)。
原文鏈接:http://www.cnblogs.com/repository/archive/2011/01/17/1937265.html
【編輯推薦】