在数据库设计中使用rowguid作为唯一键是一个好主意吗?

时间:2009-10-30 18:45:34

标签: sql-server database-design primary-key data-modeling

SQL Server提供[rowguid]类型。我喜欢将其用作唯一主键,以标识要更新的行。如果您转储表并重新加载它,则会显示好处,而不会乱用SerialNo(标识)列。

在分布式数据库的特殊情况下,例如在笔记本电脑上的离线副本或类似的东西,没有其他工作。

你怎么看?开销太大了?

4 个答案:

答案 0 :(得分:18)

作为逻辑意义上的主键(唯一标识您的行) - 是的,绝对是完全有道理的。

SQL Server中的

BUT:,默认情况下,主键也是表上的群集密钥,并使用ROWGUID作为群集密钥一个非常糟糕的主意。有关不使用GUID进行群集的深入原因,请参阅Kimberly Tripp的优秀GUIDs as a PRIMARY and/or the clustering key文章。

由于GUID按定义是随机的,因此你会有一个可怕的索引碎片,因此在insert,update,delete和select语句上的性能确实非常差。

此外,由于群集密钥被添加到表上每个非聚集索引的每个字段,因此在使用时会浪费大量空间 - 包括磁盘和服务器RAM 16字节GUID与4字节INT。

所以:是的,作为主键,ROWGUID有它的优点 - 但如果你使用它,绝对避免使用该列作为表中的聚类键!使用INT IDENTITY()或类似的东西。

对于群集密钥,理想情况下,您应该查找四个功能:

  • 稳定(永不改变)
  • 独特
  • 尽可能小
  • 不断增加

INT IDENTITY()非常适合这种需要。是的 - 聚类键必须是唯一的,因为它用于物理定位表中的行 - 如果您选择的列不能保证是唯一的,SQL Server实际上会为您的聚类键添加一个四字节的唯一符号 - 再次,不是你想拥有的......

查看The Clustered Index Debate Continues - Kim Tripp撰写的另一篇精彩而富有洞察力的文章(“SQL Server索引的女王”),其中非常详尽地解释了所有这些要求。

MARC

答案 1 :(得分:6)

rowguid的问题在于,如果将它用于聚簇索引,最终会不断重新计算表格页面以进行记录插入。顺序guid(NEWSEQUENTIALID())通常效果更好。

答案 2 :(得分:1)

我们的离线应用程序用于分支机构,我们的主办公室有一个中央数据库。为了将数据库同步到中央数据库,我们在所有表中都使用了rowguid列。可能有更好的解决方案,但对我们来说更容易。到目前为止,我们在过去3年里没有遇到任何重大问题。

答案 3 :(得分:1)

与接受的答案相反,SQL Server中的uniqueidentifier数据类型确实是主群集密钥的良好候选者;只要你按顺序保持它。

使用(newsequentialid())作为列的默认值很容易实现。

如果您实际阅读Kimberly Tripp's article,您会发现顺序生成的GUID实际上是碎片化方面的主要群集密钥的合适候选者,唯一的缺点就是大小。

如果您有大量的索引很少的行,GUID中的额外几个字节可以忽略不计。如果您的行数很多且索引很多,那么问题就会复杂化,但这是您必须根据自己的情况来衡量的。

当你打算使用合并复制时,使用顺序uniqueidentifier非常有意义,特别是在处理身份种子和随之而来的困境时。

服务器calss存储并不便宜,但我宁愿拥有一个数据库,当你自动分配的标识范围重叠时,该数据库使用的空间比停顿的数据库要多一些。