使用 DATETIME2 作为 SQL 服务器 table 的主键

Use of DATETIME2 as a primary key for SQL Server table

我知道在幕后 SQL 服务器向用作索引的 DATETIME 字段添加了一个 4 字节的唯一标识符,以确保它是唯一的。这是有道理的,因为 DATETIME 的精度是毫秒级,因此两个插入可能共享同一时间。但是,DATETIME2 的精度为 100 纳秒,因此即使在最快的服务器上也足以避免重复吗?有谁知道 SQL 服务器是否自动将 4 字节唯一标识符添加到 DATETIME2?

至少在理论上应该足够了,但我有一些遗留的 tables 用于记录由于某些客户端错误、开发人员错误或业务错误而修改重复数据的更改。是这样的:

DECLARE @DataSource TABLE
(
    [value] CHAR(1)
   ,[date] DATETIME2
   ,PRIMARY KEY([value], [date])
);

INSERT INTO @DataSource ([value], [date])
VALUES ('x', SYSDATETIME());

INSERT INTO @DataSource ([value], [date])
VALUES ('x', SYSDATETIME());

(1 row affected) Msg 2627, Level 14, State 1, Line 11 Violation of PRIMARY KEY constraint 'PK__#A1CDE66__9D260824E5008401'. Cannot insert duplicate key in object 'dbo.@DataSource'. The duplicate key value is (x, 2018-10-23 08:22:24.7026304). The statement has been terminated.

因此,根据您的代码,您也可以看到类似的情况。请注意,您应该使用 SYSUTCDATETIME(),而不是 GETUCDATE() 作为第二个 returns datetime,而不是 datetime2

对于一些历史 table 我发现将主键作为主键是正常的 table PK + 更改操作(假设 char - (U)pdate, (D)elete, (I )nsert) + datetime2.

这还取决于您要进行的搜索类型。例如,您可以创建一个身份主键并让 SQL 服务器来处理它。同时,您仍然可以添加 DATETIME 列并在其上创建索引,以优化每个日期的搜索。