我认为您根本不需要 GUID。虽然 NEWSEQUENTIALID() 在页面拆分方面比 NEWID() 更好,但在大多数情况下,它仍然是一个比必要的更宽的键,并且您失去了 GUID 的唯一其他好处(您可以提前生成它们 - 您可以) t 使用 NEWSEQUENTIALID())。然而,您仍然有一个与 IDENTITY 值类似的热点问题,其中所有插入活动都在同一范围内发生。那么它真正让你收获了什么?
以下是我实施的几种替代方法,以避免多实例系统中的 GUID 需要跨系统维护唯一键值。
身份范围
如果您在多个服务器中生成身份值并且稍后需要合并这些值,请使用身份范围(具有足够大的增长余量)。在服务器一上:
CREATE TABLE dbo.Data
(
ID BIGINT IDENTITY(1000000000, 1) PRIMARY KEY
);
在服务器二上:
CREATE TABLE dbo.Data
(
ID BIGINT IDENTITY(2000000000, 1) PRIMARY KEY
);
您可能可以使用 INT 取决于您认为您将使用多少值 - 但最好提前计划并留出大量空间,而不是以后必须全部更改。除非您生成大量数据,否则几个世纪以来您都不必担心碰撞。
密钥大小:8 个字节。 (或者 4 个字节,如果你可以使用 INT。)
复合键
另一种方法是在表上只包含一个 ServerID 列,并将其作为复合键的一部分。只要您不打算扩展超过 255 台服务器,您就可以使用 TINYINT(1 字节)。在服务器一上:
CREATE TABLE dbo.Data
(
ServerID TINYINT NOT NULL DEFAULT 1,
DataID INT IDENTITY(1,1),
PRIMARY KEY (ServerID, DataID)
);
在服务器二上:
CREATE TABLE dbo.Data
(
ServerID TINYINT NOT NULL DEFAULT 2,
DataID INT IDENTITY(1,1),
PRIMARY KEY (ServerID, DataID)
);
现在,您只需在合并系统上的 FK 中携带两列(或在合并中创建一个 IDENTITY 列)......对于连接来说有点痛苦,但比携带 GUID 轻得多。
密钥大小:5 个字节。 (或 6 个字节,如果您需要升级到 SMALLINT,因为 255 个服务器还不够。)