使用uniqueidentifier作为主键

时间:2010-07-16 18:31:05

标签: sql-server database

这是个好主意吗?与整数字段作为主键相比,使用它会减慢我的数据库吗?

3 个答案:

答案 0 :(得分:4)

取自Coding Horror: IDs vs GUIDs

GUID专业人士

  • 每个表,每个数据库,每个服务器都是唯一的
  • 允许轻松合并来自不同数据库的记录
  • 允许跨多个服务器轻松分发数据库
  • 您可以在任何地方生成ID,而不必转发到数据库
  • 大多数复制方案都需要GUID列

GUID缺点

  • 比传统的4字节索引值大4倍;如果你不小心,这会产生严重的性能和存储影响
  • 调试繁琐(其中userid ='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • 生成的GUID应该是部分顺序的,以获得最佳性能(例如,SQL 2005上的newsequentialid())并启用聚簇索引

也感兴趣:

答案 1 :(得分:3)

GUID似乎是您主键的自然选择 - 如果您真的必须,您可能会争辩将其用于表的PRIMARY KEY。我强烈建议不要使用GUID列作为群集密钥,默认情况下SQL Server会执行此操作,除非您明确告知不要。

你真的需要分开两个问题:

1)主键是一个逻辑结构 - 唯一且可靠地标识表中每一行的候选键之一。这可以是任何东西,真的 - 一个INT,一个GUID,一个字符串 - 选择对你的场景最有意义的东西。

2)集群密钥(在表上定义“聚集索引”的一列或多列) - 这是物理存储相关的东西,在这里,一个小的,稳定的,不断增加的数据类型是您的最佳选择 - INT或BIGINT作为您的默认选项。

默认情况下,SQL Server表上的主键也用作群集键 - 但这不一定是这样!我个人看到将以前基于GUID的主/群集密钥分解为两个单独的密钥 - GUID上的主(逻辑)密钥和单独的INT IDENTITY上的群集(排序)密钥(1, 1)专栏。

作为Kimberly Tripp - 索引女王 - 以及其他人已多次声明 - GUID作为聚类键不是最佳的,因为由于其随机性,它将导致大量页面和索引碎片并且通常表现不佳。

是的,我知道 - 在SQL Server 2005及更高版本中有newsequentialid() - 但即使这样也不是真正完全顺序的,因此也会遇到与GUID相同的问题 - 只是不那么显着。< / p>

然后还有另一个需要考虑的问题:表格上的聚类键也会被添加到表格中每个非聚集索引的每个条目上 - 因此你真的想确保它尽可能小。通常,对于绝大多数表来说,具有2亿行的INT应该足够 - 并且与作为群集密钥的GUID相比,您可以在磁盘和服务器内存中节省数百兆的存储空间。

快速计算 - 使用INT与GUID作为主要和群集密钥:

  • 具有1'000'000行的基表(3.8 MB对15.26 MB)
  • 6个非聚簇索引(22.89 MB vs. 91.55 MB)

TOTAL:25 MB vs. 106 MB - 这只是在一张桌子上!

更多值得思考的东西 - 金佰利特里普的优秀作品 - 阅读,再读一遍,消化它!这是SQL Server索引福音,真的。

答案 2 :(得分:2)

对此有很多争论。如果您的数据库都是本地的(不是将不同的实例复制回主数据库),那么我相信增加整数是可行的方法。默认情况下,主键是群集的,因此具有单个,精简的不断增加的数字是有意义的,因为在唯一标识符的情况下,您可以导致索引和表碎片,因为它们不会增加。 在我看来,如果您确实需要唯一标识符,请创建一个不是主键但在其上具有唯一非聚集索引的单独列。