序列与身份

时间:2012-04-08 11:07:57

标签: sql sql-server tsql sql-server-2012

SQL Server 2012引入了Sequence作为新功能,与Oracle和Postgres相同。哪个序列优于身份?为什么我们需要序列?

6 个答案:

答案 0 :(得分:67)

我想您会找到答案here

  

使用列的标识属性,您可以轻松生成   自动递增数字(通常用作主键)。同   顺序,它将是一个不同的对象,你可以附加到一个   插入时的表格列。与身份不同,下一个数字为   列值将从内存中检索而不是从磁盘中检索 -   这使得Sequence明显快于Identity。我们会看到   在即将到来的例子中。

here

  

序列:SQL Server社区已请求序列   多年来,它已包含在此版本中。序列是用户   定义的对象,生成一个数字序列。这是一个   使用序列的例子。

here

  

SQL Server序列对象生成数字序列   sql表中的标识列。但序列的优势   数字是序列号对象不受单个sql的限制   表

在msdn上,您还可以阅读有关使用情况以及我们需要它的原因(here):

  

序列是用户定义的模式绑定对象,它生成一个   根据规范的数值序列   序列已创建。生成数值序列   以定义的间隔以升序或降序排列并且可以   按要求循环(重复)。与标识列不同,序列是   与表格无关。应用程序引用序列对象   接收其下一个价值。序列与序列之间的关系   表由应用程序控制。用户应用可以   引用序列对象并协调值键   多行和多个表。

     

使用CREATE创建一个独立于表的序列   SEQUENCE声明。选项使您可以控制增量,   最大值和最小值,起点,自动重启   功能和缓存以提高性能。有关的信息   选项,请参见CREATE SEQUENCE。

     

与行所生成的标识列值不同   插入后,应用程序可以获取下一个序列号   通过调用NEXT VALUE FOR函数插入行。序列   即使数字,也会在调用NEXT VALUE FOR时分配编号   永远不会插入表中。 NEXT VALUE FOR功能可以   用作表定义中列的默认值。使用   sp_sequence_get_range获取一系列多个序列号   一次。

     

序列可以定义为任何整数数据类型。如果是数据类型   未指定,序列默认为bigint。

答案 1 :(得分:18)

序列和标识都用于生成自动编号,但主要区别是标识是表依赖的,而序列独立于表。

如果您有一个需要全局维护自动编号的场景(在多个表中),您还需要在特定编号后重新启动间隔,并且还需要将其缓存以提高性能,这里是我们需要的地方序列而非身份。

以下是定义序列的真实世界示例,其实现以及序列和身份之间差异的文章。

http://raresql.com/2012/04/29/how-sequence-works-in-sql-server-2012/ http://raresql.com/2012/05/01/difference-between-identity-and-sequence/

答案 2 :(得分:12)

尽管序列比标识列提供了更多的灵活性,但我没有发现它们有任何性能优势。

我发现使用标识的性能始终比批量插入使用序列快3倍。

我插入了大约1.5M的行,性能是:

  • 14秒的身份
  • 序列
  • 45秒

我将行插入到一个表中,该表通过表默认使用序列对象:

NEXT VALUE for <seq> for <col_name>

并尝试在select语句中指定序列值:

SELECT NEXT VALUE for <seq>, <other columns> from <table>

两者都是比身份方法慢的相同因素。我使用了序列的默认缓存选项。

Arion第一个链接中引用的文章显示了逐行插入的性能,标识和序列之间的差异为10,000次插入时的16.6秒到14.3秒。

缓存选项对性能有很大影响,但更高卷(+ 1M行)的身​​份更快

根据utly4life的评论,请参阅此link进行深入分析。

答案 3 :(得分:2)

我知道这有点老了,但是想添加一个让我感到困惑的观察。

我从标识切换到序列以按顺序排列索引。我后来发现序列不会随着复制而转移。因为序列不同步,我在两个数据库之间设置复制后开始获得密钥违规。在做出决定之前,需要注意的事项。

答案 4 :(得分:1)

最近,对于身份与顺序,有些考虑。似乎MSFT现在建议顺序,如果您想保持身份无间隙。我们遇到一个问题,即身份之间存在巨大差距,但是根据此声明,突出显示的内容可以解释我们的问题,即SQL缓存了身份,重新启动后我们丢失了这些数字。

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property?view=sql-server-2017

服务器重新启动或其他故障后的连续值–由于性能原因,SQL Server可能会缓存标识值,并且在数据库故障或服务器重新启动期间某些分配的值可能会丢失。这可能导致插入时身份值出现空白。如果差距不可接受,则应用程序应使用自己的机制来生成键值。将序列生成器与NOCACHE选项一起使用可以将间隔限制为从未提交的事务。

答案 5 :(得分:0)

我发现序列的最佳用途不是替换标识列,而是创建“订单号”类型的字段。

换句话说,订单号向最终用户公开,并且可能具有业务规则。您希望它是唯一的,但是仅使用标识列也不是正确的。

例如,不同的订单类型可能需要不同的顺序,因此与内部订单相比,您可能需要一个Internet订单序列。

换句话说,不要将序列视为标识的简单替代,而应将其视为在标识不符合业务要求的情况下有用。