无间隙身份列策略



我在身份列的手中遇到了许多问题,我不想再使用它了。我想要不同的策略。最终,我想要一个无间隙的整数列,这些整数在每个行插入物上依次递增。我不确定如何实现这一目标。是否可以从包含整数序列的表中绘制,或者可以随时创建它们的函数?感谢您帮助我解决这个技术问题。

为什么要一个无间隙的值序列?

SQL Server(以及一般数据库)的原因不容易支持此功能,这是因为很难做到。本质上,您必须锁定整个桌子以进行插入,从而减慢所有内容。

通常,拥有identity主键是足够的。尽管您会得到空白,但您可以轻松地使用以下方式计算序列:

select row_number() over (order by <pkid>)

其中 <pkid>是标识,主键列。

如果您确实坚持无间隙,那么您将需要实现触发器并自己进行计算。我认为序列(没有缓存)对于下一个数字的生产就足够了。但是,您确实需要非常谨慎地插入失败。

Gordon Linoff在您的方法中指出了核心问题。由于尚不清楚您需要什么是无间隙的身份,我们只能猜测。为了查询目的,您应使用正确的语句。考虑Rownumber()lead()和lag()。如果您需要经常查询,则可以包装已建议的row_number()over(by ID订购)例如,进入名为Gaplessid的计算列中。其他选择是:

  • 具有删除索引约束的维护作业,根据rownumber更新ID列,然后读取索引

  • 将逻辑实现到您的控制层中,并使用身份插入

  • 使用复杂而不是触发器,由于性能不佳,我不建议这样做

差距是纯粹的逻辑问题。

假设插入操作可能会失败(并且可以),
任何2个并发插入操作都可能导致差距,例如 -

最后使用的值为13。

插入会议1的操作使用14.
会议2中的插入操作使用15。
从会话1插入操作失败(回滚)。
插入第2节的操作成功(提交)。

13和15之间存在差距。

由于这是一个合乎逻辑的问题,您不能用代码绕过它,因此您仍然需要序列化插入操作
您唯一可以使用自己的代码实现的目标是,如果序列化操作失败,则没有差距。

感谢您到目前为止的评论和答案。为了满足那里的哲学家,我将解释为什么我想要一个无间隙领域。它不是基于任何需求,而是需要它的脚本,这不是生产应用程序。我有一个个人DB,我正在终生,有时服务下降,重新启动计算机,或者是身份差距发生差距的任何其他原因。在一个参考表中,我有47个记录,最大身份是2024年。

除了将来的证明外,我很好奇。当我看到有很多帖子的问题时,我想找到工作或最佳实践。自从我问这个问题以来,我已经进行了更多的研究并尝试使用序列。经过一些实验后,我决定对我的应用程序可接受性能。为了从身份字段切换到序列,我制定了以下策略:

1重复DB(为了测试目的,我在DUP上进行了所有更改)2为每个ID字段创建一个序列(以1个增量启动1个无缓存)3个Alter表以添加新的ID字段(因为我无法从字段中删除身份属性)并将默认值添加为序列的下一个值4在每个参考表上更新了新的ID字段,并使用序列的下一个值5对于任何具有外键引用一张表的表格中的表,我在旧ID字段上进行了加入,并使用参考表的新字段更新了外键字段

6更改了表以更改新字段以不为空7丢下外键和主钥匙8丢下旧的ID字段9 sp_rename新名称的新字段10重新创建了主要键和外键

我唯一无法以编程方式进行的部分是重新排序这些字段,我在SSMS中的设计师中做了。展望未来,我将在数据库中使用序列。我对解决方案相当满意。

最新更新