为什么一个 SQL Server 表不能有多个 IDENTITY 列?

use*_*729 7 sql-server database-internals identity

为什么一个 SQL Server 表不能有多个标识列?

CREATE TABLE t(id INT IDENTITY, id2 INT IDENTITY)
Run Code Online (Sandbox Code Playgroud)

消息 2744,级别 16,状态 2,第 5
行 为表 't' 指定了多个标识列。
每个表只允许一个标识列。

我知道我们可以使用计算列来解决它。

根据产品文档,一张表不能有多个标识列。但为什么?背后的真正原因是什么?

Mar*_*ith 16

我认为没有任何真正的“内部”原因。元数据存储在列级别而不是表级别。它需要重新考虑标量函数,例如scope_identity()伪列语法,例如$identity现在会有歧义。

从哲学上讲,如果 的目的identity是产生唯一标识实体的东西,为什么需要两个不同的任意计算值来充当该角色?

那么好处在哪里呢?这是一个跨站点的骗局,所以我将重复我的示例 SO

SQL Server 中的标识列具有种子和自动增量。如果我们知道第一个 id 列的值,我们总是可以计算出第二个假设的 id 值应该是多少。

例如,如果这是合法的语法

create table #foo
(
bar int identity(1,10),
baz int identity(1000,1)
)
Run Code Online (Sandbox Code Playgroud)

我们不需要存储 baz,因为它可以从 bar 计算如下。

baz = 1000 + (bar-1)/10
Run Code Online (Sandbox Code Playgroud)

从 SQL Server 2012 开始,您可以使用序列默认值将尽可能多的列添加到表中。例如:

CREATE SEQUENCE dbo.Sequence1 
    AS integer 
    START WITH 1 
    INCREMENT BY 1 
    MAXVALUE 1000 
    CYCLE 
    CACHE 50;

CREATE SEQUENCE dbo.Sequence2 
    AS decimal(5,0) 
    START WITH 5
    INCREMENT BY 10
    MAXVALUE 250 
    CYCLE 
    CACHE 50;

CREATE TABLE dbo.T
(
    id integer NOT NULL DEFAULT NEXT VALUE FOR dbo.Sequence1, 
    id2 decimal(5,0) NOT NULL DEFAULT NEXT VALUE FOR dbo.Sequence2, 
);

INSERT dbo.T DEFAULT VALUES;
INSERT dbo.T DEFAULT VALUES;
INSERT dbo.T DEFAULT VALUES;

SELECT * FROM dbo.T;

DROP TABLE dbo.T;

DROP SEQUENCE 
    dbo.Sequence1, 
    dbo.Sequence2;
Run Code Online (Sandbox Code Playgroud)

结果