在 Azure 中使用 GUID 作为主键?

jga*_*fin 6 sql-server azure-sql-database

我想使用 GUID,因为它们是可移植的,并且可以更轻松地使用多个数据库。但是由于存在性能问题,这可能不是一个好主意?虽然我发现了一个 MS 博客条目,其中另有说明:http : //blogs.msdn.com/b/cbiyikoglu/archive/2012/05/17/id-generation-in-federations-identity-sequences-and-guids -唯一标识符.aspx

我已经阅读了一种替代方法,其中 datetime2 列用作聚集索引,Guid 用作 PK。因为我的大多数表格都有一个CreatedAtUtc列,这对我来说应该是一个可行的选择。但这真的有用吗?

所以我的问题是我是否应该使用 GUID 来获得可移植性,或者是否有更好的解决方案?

(使用 GUID,我还可以在我的代码中创建 Id 并在提交之前做更多的事情)。我还创建了一个 COMB 生成器,它应该比常规 GUID 更适合 MSSQL。

Ken*_*her 8

GUID 只是出于几个原因才真正导致性能问题。

首先是它们的大小。您使用的是 16 字节标识符,其中 int(4 字节)甚至 bigint(8 字节)要小得多。这在宽桌或短桌上并不重要。如果您的表相当窄,那么百分比增加当然更大。2000 字节宽度与 2012 字节宽度实际上并不是什么大问题,而 20 与 32 显然差异更大。如果你的表会很大,有数百万甚至上百万行,那么你添加的 8-12 个字节将比只有 1000 行的表产生更明显的差异。另一方面,如果您需要便携性,那么您可能愿意接受空间问题。

接下来是仅当 GUID 是聚集索引的一部分时才会出现的问题。如果 GUID 是聚集索引,则 GUID 将包含在所有非聚集索引的叶级页面中。因此,相比之下,具有整数聚集索引的表只会向叶页添加 4 个字节,而 GUID 将添加 16 个字节。随着时间的推移,这可能会增加,尤其是对于多个索引。它当然也会增加使用该索引的读取次数,因为每页可以容纳更少的条目。GUID 使用聚集索引的另一个问题是它们通常不按顺序排列。这意味着在插入期间潜在的页面拆分。您提供的链接提到,这与 Azure 中的写入时间相比并没有大幅增加。

在我看来,如果您已经有一个 CreatedAtUTC 列,那么继续并使其成为聚集索引并使用 GUID 作为您的主键。 这里还有一个链接,我找到了 Azure 团队关于这个主题的博客。 当然,他自己处理喜欢 GUID,所以他有点偏见。使用 CreatedAtUTC 作为聚集索引的另一个好处是它不会改变。这意味着最少的行移动。