我正在为我的公司正在启动的新数据库制定数据库标准。我们试图定义的一件事是与唯一标识符相关的主键和聚集索引规则。
(注意:我不想讨论使用 UniqueIdentifier 作为主键或聚集索引的利弊。网上有大量关于此的信息。这不是讨论。)
所以这是让我担心的场景:
假设我有一个以 UniqueIdentifier 作为聚集索引和主键的表。让我们称之为ColA。我将 ColA 的默认值设置为 NewSequentialId()。
使用该 NewSequentialId() 我插入三个连续的行:
{72586AA4-D2C3-440D-A9FE-CC7988DDF065}
{72586AA4-D2C3-440D-A9FE-CC7988DDF066}
{72586AA4-D2C3-440D-A9FE-CC7988DDF067}
然后我重新启动我的服务器。NewSequentialId的文档说“重新启动 Windows 后,GUID 可以从较低的范围重新开始,但仍然是全局唯一的。”
所以下一个起点可以低于上一个范围。
所以重新启动后,我再插入 3 个值:
{35729A0C-F016-4645-ABA9-B098D2003E64}
{35729A0C-F016-4645-ABA9-B098D2003E65}
{35729A0C-F016-4645-ABA9-B098D2003E66}
(我不确定该 guid 在数据库中的确切表示方式,但假设因为这个以 3 开头,而前一个以 7 开头,所以 3 个比 7 个“小”。)
当您在聚集索引的中间进行插入时,必须重新映射索引。(至少我的 DBA 是这样告诉我的。)每次重新启动时,我都会冒着让我的新 UniqueIdentifier 范围正好位于其他先前范围中间的风险。
所以我的问题是:由于下一组 UniqueIdentifiers 将小于上一组,每次插入都会导致我的聚集索引洗牌吗?
如果不是,为什么?SQL Server 是否知道我正在使用 NewSequentialId?它有什么办法弥补吗?
如果不是,那么它怎么知道我接下来要插入什么?也许接下来的一百万个插入将从 3 开始。或者他们将从 7 开始。它怎么知道?
还是它不知道,只是保持一切井井有条。如果是这种情况,那么一次重新启动可能会极大地影响性能。(这让我觉得我需要自己的不受重启影响的自定义 NewSequentialId。)对吗?还是有一些我不知道的魔法?
编辑:在我的标准中强烈建议不要将 GUID 作为聚集索引。正如我上面所说,有很多原因表明这是一个坏主意。我试图找出这是否是另一个原因。