Guid是数据库的最佳标识数据类型吗?

时间:2008-12-12 08:49:36

标签: sql-server database-design replication guid

它连接到BI并合并来自不同数据源的数据,并使该过程更加流畅。

是否存在从没有Guids的数据库到没有信息丢失的Guids版本的最佳迁移策略?

8 个答案:

答案 0 :(得分:20)

请记住,PK的GUID(或'unique_identifier')是一个糟糕的选择,因为许多PK都有聚簇索引(因此所有行都以索引顺序存储在磁盘上)。由于GUID是随机的,因此不确定在索引末尾会附加新行,但可以将其插入索引的中间。这会导致磁盘垃圾,因为必须移动行。

如果您考虑guid,至少使用sqlserver 2005或更高版本和NEWSEQUENTIALID()获取PK值,以获得始终大于最后一个的顺序guid,因此始终附加在索引的末尾。如果您没有使用sqlserver(但是例如postgresql或者您正在使用oracle并使用CHAR(32)或其他类型),请考虑COMB(参见:http://www.informit.com/articles/article.aspx?p=25862

答案 1 :(得分:14)

阅读Frans Bouma的回答后编辑,因为我的回答已经被接受,因此被移到了顶部。谢谢,弗兰斯。

GUID确实具有很好的独特价值,但是由于它们的复杂性,它们并不是人类可读的,这可能会使支持变得困难。如果您要使用GUID,您可能需要考虑在做出选择之前对批量数据操作进行一些性能分析。请注意,如果您的主键是“群集”,则GUID不合适。

这是因为聚簇索引会导致在插入/更新的表中对行进行物理重新排序。由于GUID是随机的,因此每个插入都需要移动表中的实际行以为新行腾出空间。

我个人喜欢在我的数据上有两个“键”:

1)主键
具有群集主键的唯一数字值。这是我系统的每行内部 ID,用于唯一标识行和外键。

如果您正在使用数据库复制,则身份可能会导致问题(SQL Server将自动为合并复制表添加“rowguid”列),因为每个服务器实例都会维护身份种子,并且您将获得重复项。

2)外部密钥/外部ID /业务ID
通常,还优选具有“外部ID”的附加概念。这通常是具有唯一约束的字符字段(可能包括另一列,例如客户标识符)。

这将是外部接口使用的值,并将暴露给客户(他们无法识别您的内部值)。这个“业务ID”允许客户使用对他们有意义的值来引用您的数据。

答案 2 :(得分:4)

您可能需要设施来追踪来源以进行审计,尤其是财务数据。

即使您在仓库系统中使用合成密钥(如果您有多个数据源,您几乎肯定想要这样做),您仍然需要支持审计。在系统中的表中放置一个“数据源”和“自然键”列,并使用源代码填充它们,并在源代码中唯一标识该记录的表示。

如果你这样做,合成键只需要是足够宽的整数或数值来存储足够的值(如果< 4b行,则数量为int,如果超过则为数字)。这意味着它们比GUID更具可读性。

答案 3 :(得分:2)

以下项目可能会有所帮助,或至少可以激励您解决此问题。

https://github.com/twitter/snowflake

答案 4 :(得分:1)

任何可以唯一标识记录的东西都是良好的身份数据类型。 GUID通常很好,但如果您实际拥有来自源数据的唯一ID,则它不是最佳标识。 GUID是一个随机整数值,保证是唯一的;但是,在集成情况下,您经常需要检测重复的信息,而不仅仅是匹配记录。

答案 5 :(得分:1)

没有“最佳”标识数据类型。各种选择有不同的优点和缺点。我经常使用GUID,但我必须定期处理断开连接的客户端和合并复制,因此选择是合适的。如果您不必处理复制(即用户在与中央数据库断开连接时添加新记录的情况),则自动递增int字段是更好的选择。

答案 6 :(得分:1)

GUID在数据复制方案中更好,使用“身份”方法时必须注意不要在数据库之间复制数据之间发生冲突。 希望这会有所帮助。

答案 7 :(得分:0)

我以前根本不喜欢GUID,但我已经爱上了它。我喜欢它,因为它相对统一并且被采用,并且我最终通过使用它来编写更少的代码,并维护代码,而不是通常编写和维护的代码。

对于文件的存储尤其有用,您需要在具有潜在大量文件的目录(包括预先存在的文件)中保证文件名是唯一的。