SQL Server:按时间戳聚类; 优点缺点

Ian*_*oyd 4 sql-server timestamp rowversion clustered-index

我在SQL Server中有一个表,我希望将插入添加到表的末尾(而不是将它们插入中间的聚类键).这意味着我希望按一些列聚集的表不断增加.

这可以通过在datetime列上进行聚类来实现:

CREATE TABLE Things (
    ...
    CreatedDate datetime DEFAULT getdate(),
    [timestamp] timestamp,        

    CONSTRAINT [IX_Things] UNIQUE CLUSTERED (CreatedDate)
)
Run Code Online (Sandbox Code Playgroud)

但我不能保证两个Things人不会有同一时间.因此,日期时间列无法真正实现我的要求.

我可以添加一个虚拟标识 int列,并在其上添加集群:

CREATE TABLE Things (
    ...
    RowID int IDENTITY(1,1),
    [timestamp] timestamp,        

    CONSTRAINT [IX_Things] UNIQUE CLUSTERED (RowID)
)
Run Code Online (Sandbox Code Playgroud)

但你会发现我的桌子已经成了一个timestamp专栏; 保证单调增加的列.这正是我想要的候选群集密钥的特征.

所以我将表聚集在rowversion(又名timestamp)列上:

CREATE TABLE Things (
    ...
    [timestamp] timestamp,        

    CONSTRAINT [IX_Things] UNIQUE CLUSTERED (timestamp)
)
Run Code Online (Sandbox Code Playgroud)

我没有添加虚拟标识 int列(RowID)来确保订单,而是使用我已有的.

我正在寻找的是为什么这是一个坏主意的想法; 以及其他更好的想法.

注意:社区维基,因为答案是主观的.

mar*_*c_s 9

所以我将表集中在rowversion(又名时间戳)列上:我没有添加虚拟标识int列(RowID)以确保订单,而是使用我已有的.

起初听起来可能是一个好主意 - 但这几乎是你最糟糕的选择.为什么?

群集密钥的主要要求是(有关更多详细信息,请参阅Kim Tripp的博客文章):

  • 稳定
  • 狭窄
  • 独特
  • 如果可能的话,不断增加

rowversion违反了稳定的要求,这可能是最重要的要求.行的rowversion随着对行的每次修改而改变 - 并且由于您的聚类键被添加到表中的每个非聚集索引,因此您的服务器将不断更新非聚集索引的负载并浪费大量这样做的时间.

最后,添加一个虚拟标识列可能是一个更好的替代您的情况.第二个最佳选择是datetime列 - 但是在这里,您确实冒着SQL Server必须在重复发生时为条目添加"唯一符号"的风险 - 并且准确度为3.33ms,这肯定会发生 - 不是最佳的,但是肯定比rowversion想法好多了......