我们有一个使用 UniqueIdentifier 作为每个表的主键的系统。我们已经注意到这是一个坏主意。我看过关于这个主题的类似帖子,但我对任何 MS SQL 性能和由于这个决定可能遇到的其他潜在问题感兴趣。
12 回答
有优点也有缺点:
这篇文章涵盖了所有内容。
GUID 优点
- 每个表、每个数据库、每个服务器都是唯一的
- 允许轻松合并来自不同数据库的记录
- 允许跨多个服务器轻松分布数据库
- 您可以在任何地方生成 ID,而不必往返于数据库
- 大多数复制方案无论如何都需要 GUID 列
GUID 缺点
- 它比传统的 4 字节索引值大 4 倍;如果您不小心,这可能会对性能和存储产生严重影响
- 调试麻烦(其中 userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
- 生成的 GUID 应该是部分顺序的,以获得最佳性能(例如,SQL 2005 上的 newsequentialid())并启用聚集索引
上周我写了一篇关于这个的帖子,其中包含一些代码来告诉你会发生什么:一些简单的代码来显示 Newid 和 Newsequentialid 之间的区别
基本上,如果您使用 newid() 而不是 Newsequentialid() 如果您的 PK 是聚集索引(默认情况下将是),则会出现可怕的页面拆分
就个人而言,我会为 PK 使用 int 或 bigint,但对于那些需要为该记录提供不可猜测的“键”的情况,只需放入另一个“Guid”列,并在插入行时生成 Guid。
如果您需要对大型集合(比如说 100,000 个)进行连接,那将会很糟糕。去过那里,受苦了。
后来编辑:我还遇到了一个更糟糕的问题(不能称之为“方法”):将 GUID 存储在 char(36) 列中!
GUID 是一种用于识别行的强大数据类型,因为它几乎可以保证是唯一的,这允许很多灵活性,例如您可以在应用程序层生成 Guid,这可以大大简化保存您的关系。
如前所述,最大的缺点是如果您的 PK 是聚集索引,则会发生页面拆分;但是,您可以通过两种方式解决此问题。您可以使用 NewSequentialId() 或者您可以将 PK 设置为非集群。我建议您根据数据要求构建数据库,如果您需要 GUID,请使用它,然后围绕它进行优化。并在您的环境中验证其性能。
Jimmy Nilsson写了一篇关于 GUID 与 INT 和组合 GUID 的精彩文章。结论...不要害怕 GUID...无论如何,复合指南。
如果您想快速写入数据库,那就不好了。如果您要进行大量插入,那么最好使用不同的数据类型。
这是一个“坏”的想法。它可能很慢。您也不是很适合使用索引进行快速搜索。我们使用 GUID 或 UniqueIDs 的唯一实时是当我们必须保持跨数据库的数据项连接时,通常是当我们有一个服务器数据库和一个应用程序的本地数据库(对于断开连接的系统)时。除了指导之外,您真的没有其他方法可以将事物保持在一起。对于索引和主键,您希望使用整数值并尝试将事物与关联表链接起来,而不是到处使用 guid。
我发现使用它们的最佳理由是在复制数据库时。即使这样,也可以有更好的方法来处理这些问题,比如包括 ID 和位置的多部分主键。如果您不需要该功能,我建议坚持使用某种形式的整数。
它还可以真正减慢您的数据库读取速度,因为除非另有说明,否则主键是使用聚集索引创建的。guid 是最差的聚集索引类型,而 int 或 bigint 将用作更好的主键或聚集索引
我不会说它本身是坏的。我和很多发誓的人谈过,虽然我觉得它有点冗长。我同意routeNpingme
并说您应该使用常规整数作为 ID,但还包括 GUID(无论如何您都需要复制)“以防万一”
如果您正在进行任何类型的数据库复制,GUID 是您最好的朋友!