使用 bigint 作为非聚集键和 guid/UNIQUEIDENTIFIER 作为主键非聚集

using bigint as non clustered key and guid/UNIQUEIDENTIFIER as primary key non clustered

阅读许多博客后,我决定创建以 guid/UNIQUEIDENTIFIER 作为主键的表,但使用非聚集索引和 bigint 作为聚集键。

首先,在这种情况下正确的 DDL 语法是什么。另外,我认为使用 bigints 作为外键是正确的选择。这是正确的吗?

这是十人份的开胃菜:

IF OBJECT_ID('dbo.Table1', 'U') IS NOT NULL
  DROP TABLE dbo.Table1; 

CREATE TABLE dbo.Table1
(
    [Table1Id] [BIGINT] IDENTITY(1,1) NOT NULL,
    [Table1Guid] [UNIQUEIDENTIFIER] NOT NULL,
    [PayLoad] NVARCHAR(200) NULL
PRIMARY KEY CLUSTERED 
(
    [Table1Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
) 

CREATE NONCLUSTERED INDEX IX_Table1_Table1Guid
    ON dbo.Table1 (Table1Guid); 
GO

实际上,当您创建 table 时,默认主键被创建为聚簇索引。但是您可以创建非聚集主键并在另一列上添加聚集索引。语法为:

CREATE TABLE [dbo].[Table1](
    [Table1Id] [BIGINT] IDENTITY(1,1) NOT NULL,
    [Guid] [UNIQUEIDENTIFIER] NOT NULL,
    [PayLoad] NVARCHAR(200) NULL
) 
GO

ALTER TABLE [dbo].[Table1] ADD CONSTRAINT [PK_Table1] PRIMARY KEY NONCLUSTERED ([Guid])
GO

CREATE UNIQUE CLUSTERED INDEX IX_Table1_Table1Id ON dbo.Table1 (Table1Id)
GO

现在介绍 guid 列上的主键。由于需要 space,因此 guid primary key 通常不是一个好主意。

摘自Exam 70-461: Querying Microsoft SQL Server 2012:

The storage requirements for your surrogate key can have a cascading effect if your clustered index is defined on the same key columns (the default for a primary key constraint). The clustered index key columns are used by all nonclustered indexes internally as the means to locate rows in the table. So if you define a clustered index on a column x, and nonclustered indexes—one on column a, one on b, and one on c—your nonclustered indexes are internally created on column (a, x), (b, x), and (c, x), respectively.

除非你真的需要这样的 PK(例如在分布式系统中,当你需要跨多个系统的唯一性时)我不建议使用 guids 作为 PK,在在运营中最少 tables.