我写了一个查询来自动增加新记录的序列号,它在单个调用中工作正常。
insert into testTable (sequence_no)
case when exists (select sequence_no from testTable)
then (select top(1) sequence_no +1 from testTable order by sequence_no desc)
else '1'
end as sequence_no
然后我在上面添加一个线程注释,循环 100000 次,打开 2 个线程并同时运行它。
线程1:
declare @cnt INT =0;
while @cnt<100000
begin
insert into testTable (sequence_no, thread_no)
case when exists (select sequence_no from testTable)
then (select top(1) sequence_no +1 from testTable order by sequence_no desc)
else '1'
end as sequence_no, '1' as thread_no
SET @cnt = @cnt + 1;
END;
线程2:
declare @cnt INT =0;
while @cnt<100000
begin
insert into testTable (sequence_no, thread_no)
case when exists (select sequence_no from testTable)
then (select top(1) sequence_no +1 from testTable order by sequence_no desc)
else '1'
end as sequence_no, '2' as thread_no
SET @cnt = @cnt + 1;
END;
结果大约 70% 请求成功,其他失败
违反 PRIMARY KEY 约束“sequence_no”。无法在对象“dbo.testTable”中插入重复键。
我认为如果我在每个请求上使用一个事务就可以解决,但结果是相似的,大约 70% 成功,而其他人则因 PK 重复而失败。
这是否意味着我的做法不利于序列号生成?
有人可以给我改进吗?
每个 RDBMS 系统通常都有自己的“自动编号”(通常用于 PrimaryKeys)设置。
MySql、Ms-Sql-Server、ORACLE(文章显示了每种语法的 3 种不同的语法……仅在一个 url 上)
https://www.w3schools.com/sql/sql_autoincrement.asp
PostGres:
https://chartio.com/resources/tutorials/how-to-define-an-auto-increment-primary-key-in-postgresql/
您的问题带有 (microsoft)sql-server 标记,因此我将其粘贴。
SQL Server 的语法 以下 SQL 语句将“PersonKey”列定义为“Person”表中的自增主键字段:
CREATE TABLE dbo.Person ( PersonKey int IDENTITY(1,1) PRIMARY KEY, LastName varchar(255) NOT NULL, FirstName varchar(255) );
不要重新发明轮子。
因此,除非您(尝试)在 < 2 秒内插入一百万行......使用已经存在的内容。
意见。
您不应该关心每个主键是否完全按顺序排列。又名,“差距”应该没问题。
如果你认为你需要完美的测序,你需要问自己“为什么”。
主键必须是唯一的。有“顺序”有助于索引。
但
订购了 1,2,3,6,7,9,11。(4,5,8 不见了,但它们不见了真的很重要吗?)
我要补充一点,自 2016 版以来,Sql Server 女士已经添加了“序列”(或者是 2014 年?)
有理由选择其中之一。
https://www.sqlshack.com/difference-between-identity-sequence-in-sql-server/
2 美分的解释是序列可以提供一系列值。而且它不绑定到单个表(就像身份一样)。
但实际上,您最终会在值中有更多“间隙”......因为一旦请求序列,就永远不会重新生成相同的值......即使 INSERT 的潜在行实际上并未使其成为插入行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句