具有唯一标识符的表上的主键选择

dar*_*ect 6 sql-server primary-key identity

我正在重新考虑我对表主键的选择,并希望得到一些输入。

一些上下文:我们正在构建一个 REST API,客户端可以在其中访问由 GUID 标识的“资产”。因此,我们数据库中的 Asset 表类似于:

CREATE TABLE [dbo].[Asset](
    [Id] [uniqueidentifier] NOT NULL,
    [TypeId] [int] NOT NULL,
    [Date] [datetime] NOT NULL,
    [Title] [varchar](1000) NULL,
    [Description] [varchar](max) NULL,
    [Created] [datetime] NOT NULL,
    [Modified] [datetime] NOT NULL,
    [PublisherFields] [xml] NULL,
    [StatusId] [int] NOT NULL,
 CONSTRAINT [PK_Asset] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
Run Code Online (Sandbox Code Playgroud)

我们在使用这种结构时遇到了一些问题,特别是表上的聚集索引很快变得碎片化,现在我们已经达到了无法重建它的程度(因为 Azure 对查询时间的限制)。

进一步的研究表明,使用 uniqueidentifier 作为聚集索引并不总是一个好的选择,因为 newid() 不会按顺序生成 ID(除非您使用 newsequentialid(),但 Azure 也不允许这样做) .

简单的解决方案似乎是引入一个虚拟列并将聚集索引添加到其中。设计指南说好的聚集索引应该是连续的和不变的,所以最简单的答案似乎是一个标识列。这将使我的表变成这样:

CREATE TABLE [dbo].[Asset](
        [Id] [bigint] IDENTITY(1,1), <---- NEW
        [AssetId] [uniqueidentifier] NOT NULL, <---- Renamed
        [TypeId] [int] NOT NULL,
        [Date] [datetime] NOT NULL,
        [Title] [varchar](1000) NULL,
        [Description] [varchar](max) NULL,
        [Created] [datetime] NOT NULL,
        [Modified] [datetime] NOT NULL,
        [PublisherFields] [xml] NULL,
        [StatusId] [int] NOT NULL,
     CONSTRAINT [PK_Asset] PRIMARY KEY NONCLUSTERED <--- Now NonClustered
    (
        [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
    )
Run Code Online (Sandbox Code Playgroud)

聚集索引也将添加到ID列中。这似乎是一个明智的选择吗?我可能会质疑在表上有一IDENTITY列不是主键的意义,但我的推理是一IDENTITY列用于获取适合聚集索引的自动递增性质。这也可能令人困惑……当有人引用“资产 ID”时,他们在谈论哪一列?[ AssetId] 列,还是资产表的 [ ID] 列?

欢迎提出建议和替代方案。

小智 0

虽然我不在 Azure 中工作,但我肯定会建议 SQL Server 使用顺序递增的键,例如 newsequentialid,但既然你说 Azure 不支持它......请遵循 Kimberly Tripp 在http://www. sqlskills.com/blogs/kimberly/guids-as-primary-keys-andor-the-clustering-key/

身份似乎是避免分裂的更好选择。