我正在使用 newsequentialid 为表中的主键生成 GUID。
根据文档 (https://learn.microsoft.com/en-us/sql/t-sql/functions/newsequentialid-transact-sql?view=sql-server-ver15(,不能保证按顺序生成顺序 GUID。
重新启动 Windows 后,GUID 可以从较低的范围重新启动, 但仍然是全球独一无二的
基本上,在您重新启动计算机之前,它们是有序的。
对于自动增量主键,将其作为聚集索引是有意义的,因为可以保证插入的行将位于末尾。
对于 GUID 主键,将其作为聚集索引没有意义,因为它是随机的,插入的行不太可能位于末尾。
顺序GUID 主键呢?主键应该是聚集索引,还是应该尝试查找另一列,如 DateCreated 字段?问题是像DateCreated这样的字段不会是一个唯一的字段。如果我没有任何字段是唯一字段,我应该将什么作为聚集索引?
对于聚集索引,顺序 GUID 比非顺序 GUID 安全得多。 通常,数据库不会特别频繁地重新启动。 确实,重新启动可能会导致页面拆分和碎片,但这通常不是太大的考虑因素,因为重新启动很少见。
也就是说,主键不需要是聚集索引键。 您可以使用identity
列或创建日期/时间作为聚簇索引,这几乎消除了这个问题。
我前段时间写了一篇关于这个的长文。 TL/DR 是使用顺序 GUID 作为聚集索引键是可以的。 GUID 实际上插入在索引的中间,但具有少量(此处为一个(的中间索引插入点不会导致昂贵的页面拆分或导致有害的碎片。
良好的页面拆分和顺序 GUID 密钥生成
此相同的行为适用于将复合键用作聚集索引,其中前导键列的基数较低。 例如(CustomerId,TransactionId(。 每个 CustomerId 将有一个半整页,其中包含用于下一个事务 ID 的空间,当该页面填满时,将分配一个新页面。