日期:2014-05-17  浏览次数:20483 次

请教一个关于主键自增长列的问题
我们在创建表的时候一般习惯这样。

CREATE TABLE tablename
(
tid INT PRIMARY KEY IDENTITY(1,1)
)

但最近我看到一个项目里面是用另一种方式管理自增列的:
1.创建一个管理自增列的表

CREATE TABLE table2
(
tablename NVARCHAR(99),
currentval BIGINT
)

然后有个存储过程来更新这个管理表的数据.
请问这样做的目的是什么?有啥好处?跟传统的IDENTITY(1,1)有啥区别?

------解决方案--------------------
我觉得还是identity的方法更好,当然,前提是identity能满足需求的。

sql server提供的identity的性能肯定是更好。

而通过创建一个表,里面存储了表名这个表中的当前id值,当有多个表,而每个表有多个线程,都需要取currentval,可能会导致性能问题
------解决方案--------------------
identity 简单方便,而自己维护sequence也是可以的,事实上不少项目就采用后者。。
------解决方案--------------------
性能来说,自增列好,但是管理层面来说,第二种方法好点。
因为如果自增列表中的数据如果删除,就会出现数据空缺。

个人还是推荐自增列。
------解决方案--------------------
引用:
Quote: 引用:

性能来说,自增列好,但是管理层面来说,第二种方法好点。
因为如果自增列表中的数据如果删除,就会出现数据空缺。

个人还是推荐自增列。
如果按第二中方式生成的标识列在删除的时候也会出现数据空缺,因为currentval只记录最大标识

看你怎么管理了。
------解决方案--------------------
第二种方法是通过代码来维护数据库的自增性,因为同一时刻获取的最大id是同一个,所以并发下面可能比较好,单纯的Identity的自增方法满足不了高并发下的ID维护
------解决方案--------------------
引用:
Quote: 引用:

我觉得还是identity的方法更好,当然,前提是identity能满足需求的。

sql server提供的identity的性能肯定是更好。

而通过创建一个表,里面存储了表名这个表中的当前id值,当有多个表,而每个表有多个线程,都需要取currentval,可能会导致性能问题
如果多个表同时有大量数据插入就会有延迟,使用第二中方式是不是为了对应高并发防止标识列重复?


这个确实有可能,在并发插入大量数据,可能会有热点块的问题,会有闩锁。这个可以考虑通过其他字段来建立聚集索引,这样可以避免热点块的问题。

但是第二个表,我觉得,在并发插入大量数据的时候,也会有性能问题,比如同时有1000个同时插入,应该也会有热点块问题,甚至阻塞问题
------解决方案--------------------
对于第二种方式,个人的感觉:
1、有可能是因为可移植性考虑吧,因为其他数据库不一定有自增长列。
2、我见过几个系统用这种方式管理的,并不是管理的自增长列,而是管理类似单号这样的列,因为这样的列不单是自动增长的,有可能是前面有字母,后几位才是自动增长的。
------解决方案--------------------
第2中方法有以下好处:
1、可以防止由于删除数据导致原有ID资源的浪费,为空掉很多ID
2、可以提高并发性,例如如果批量插入数据,那么可以在ID表中也采用批量插入的方式插入ID
3、ID类型的选择也多样化,不像自增长只能是整型