弃用数据库自增ID,曝光一下我自己用到的解决方法 (转发)
2011-01-19 10:59
465 查看
在平时的项目开发中,我相信有很大一批人都在用这个数据库自增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 会对我们经常调用的存储过程有缓存,再一点,这个表的数据应该不会很大,最多上千条(一个项目中上千个表的情况应该不是很多吧)。所以检索不是什么问题,何况是根据表名来检索(表名列已是主键)。
2:并发问题。
很多人有提到!不过凡事都是一把双刃剑,这就好比做优化,要么以时间换空间,要么以空间换时间,这个世界上根本不存十全十美的事物!
个人拙见!仅此而已!
转发自:/article/5273628.html
优点:节省时间,根本不用考虑怎么来标识唯一记录,写程序也简单了,数据库帮我们维护着这一批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 会对我们经常调用的存储过程有缓存,再一点,这个表的数据应该不会很大,最多上千条(一个项目中上千个表的情况应该不是很多吧)。所以检索不是什么问题,何况是根据表名来检索(表名列已是主键)。
2:并发问题。
很多人有提到!不过凡事都是一把双刃剑,这就好比做优化,要么以时间换空间,要么以空间换时间,这个世界上根本不存十全十美的事物!
个人拙见!仅此而已!
转发自:/article/5273628.html
相关文章推荐
- 弃用数据库自增ID,曝光一下我自己用到的解决方法
- 弃用数据库自增ID,曝光一下我自己用到的解决方法
- 弃用数据库自增ID,曝光一下我自己用到的解决方法之---终结篇
- 弃用数据库自增ID,曝光一下我自己用到的解决方法
- 弃用数据库自增ID,曝光一下我自己用到的解决方法
- 弃用数据库自增ID,曝光一下我自己用到的解决方法之---终结篇
- 在备份SQL Server 2005数据库时出现“在处理‘XXX’元数据(数据库IDXX,文件IDXXX)时出错”的解决方法
- oracle数据中删除数据时提示“记录被另一个用户锁住” 解决方法: 1、查看数据库锁,诊断锁的来源及类型: select object_id
- 不想在地址栏中曝光你数据库自增ID的方法
- JPA Save()对象后返回该对象在数据库中的ID的解决方法(亲测有效)
- 你不从地址栏中增加曝光量所需的数据库ID方法
- sql server 还原数据库后,删除用户,提示数据库主体在该数据库中拥有架构,无法删除解决方法
- SQL Server 2005 Express附加(Attach)的数据库为“只读”的解决方法
- php在执行mysql存储过程后执行其他数据库操作问题解决方法
- 访问IIS元数据库失败多种解决方法
- SQL Server 2005还原数据库时出现“备份集中的数据库备份与现有的数据库不同”解决方法 (转载)
- SQL2005的SQL Server Management Studio对大数据库操作超时解决方法
- 浏览器事件 ID 8021 和事件 ID 8032 的常见原因以及相应的解决方法
- sql2008“备份集中的数据库备份与现有的xx数据库不同”解决方法
- SQL SERVER 2005 数据库状态为“可疑”的解决方法