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/
身份似乎是避免分裂的更好选择。
| 归档时间: |
|
| 查看次数: |
2591 次 |
| 最近记录: |