身份列有什么特别之处?
我很确定有一个正当的理由,但我试图更好地理解 SQL。
那么,一个身份列有什么特别之处,以至于回想起来不能轻易添加呢?
为什么每次插入新行时,这不仅仅是一个单一的 int/bigint 标志?
每行是否有任何物理存储的东西,这是一个困难的过程?
身份列有什么特别之处?
我很确定有一个正当的理由,但我试图更好地理解 SQL。
那么,一个身份列有什么特别之处,以至于回想起来不能轻易添加呢?
为什么每次插入新行时,这不仅仅是一个单一的 int/bigint 标志?
每行是否有任何物理存储的东西,这是一个困难的过程?
标识本身不会在表上插入值,它取决于
INSERT
命令,并且表上的旧行需要UPDATE
. 如果您尝试UPDATE
使用标识列,则会收到如下错误:每个功能都有目的和限制。标识的目的不是为了更新值。
实际上就是这样。CREATE TABLE ( Transact-SQL) IDENTITY (Property)说:
因此,您的
IDENTITY
列有一个标志,它在插入新行时向 SQL Server 询问其中一个值。从文档的备注部分,
IDENTITY
您可以看到该功能有一些限制,原因是:如果我正确理解了您的问题,那么您不是在问如何创建具有新
IDENTITY
值的新列。您在问为什么我们不能ALTER TABLE tbl ALTER COLUMN col int IDENTITY
在现有列上发布。正如你所说,它实际上是一个
DEFAULT
带有计数器的约束。我认为答案很简单,它从未实施过,显然没有足够的人要求它。所以我们必须使用变通方法。
我认为添加这个特性没有什么大的困难,除了它必须被指定、实现和测试。因此,如果您需要此功能,请投票支持 Azure 上的现有反馈问题。
记住罗纳尔多回答的第一段和最后一段,另一件需要注意的事情是,
IDENTITY
事后没有适当的机制可以在表格中添加一个。该IDENTITY
列周围有几个参数,例如种子和增量值,它们甚至都可以是负数。IDENTITY
列不需要是主键的一部分,也不依赖于它。如果能够在
IDENTITY
事后向表中添加一列,那么将无法关联这些IDENTITY
值应该属于哪些行。需要在 SQL Server 中编写额外的机制,以提供一种方法来指定如何IDENTITY
为每一行生成适当的值,可能使用ORDER BY
子句。但即使这样也不能解决所有问题,因为如果用户指定一组非唯一的字段
ORDER BY
(但希望IDENTITY
是唯一的),那么应该怎么做?...它可以像窗口函数IDENTITY
一样随机选择一个ROW_NUMBER()
确实如此,但它会使IDENTITY
函数变得不确定,这对于列来说不是一个很好的特征IDENTITY
。或者它可能只是生成重复IDENTITY
值而不保证唯一性,这很好,但不能解决用户的问题。长话短说,如果 Microsoft 想要提供一种
IDENTITY
在表格填充行后向表格添加列的方法,这是可能的,但需要对应该如何完成进行一些思考。它也是一个不经常需要的功能,因此限制这样做的能力的当前设计是普遍可以接受的。您不能向现有列添加标识,但可以开始使用序列。
https://learn.microsoft.com/it-it/sql/t-sql/statements/create-sequence-transact-sql?view=sql-server-ver15
也许这可以给你一个选择。
您可以创建一个带有
IDENTITY
列的新空表,并使用ALTER TABLE SWITCH
将行切换到新表定义作为仅限元数据的操作,因此这可以用于以繁琐的方式有效地切换身份属性。该
IDENTITY
属性只是某些系统表中的元数据属性,如果实施,这很容易更新。同时,ALTER TABLE ... SWITCH
不要求该属性在源和目标中相同的事实可以用来有效地实现这一点。您仍然需要删除和重命名,但这会有所帮助,因为它只是更改了表元数据。行没有移动,最终您会得到与现在包含一
IDENTITY
列的表相关联的完全相同的数据和索引页。有关示例,请参阅为什么要删除不受支持的列上的 Identity 属性。