使用uuid作为主键和/或代理键?

5
我们需要在大多数对象和数据库表中添加UUID。您会将UUID用作替代键,还是将其用作自然键并增加一个生成的替代键序列,即使用私有替代键,并添加列/属性来保存UUID?我发现它经常直接用作替代/主键。但是我不喜欢这个想法。一个UUID可以被视为自然键,因为它应该是一个具有全局意义的唯一标识符,就像任何其他自然键一样,独立于系统的特定实现,也就是说,如果您将数据移动到另一个系统,UUID必须保持不变,而替代键从定义上没有真正而持久的含义。假设我们有一个账户表。传统上,会有一些内部替代键和由账号号码(如打印账单等)构成的自然键。虽然UUID不像账号数字那么“可读”,但我认为UUID更像自然键,因为它可以像账号数字一样用于唯一且不变地引用特定账户。传统替代键从不出现在系统之外,因为它完全是私有的,并且随时可以更改,无需存在任何外部引用。在这个意义上,UUID不是典型的替代键吗?

1
自然键是通过基于数据创建键来形成的。UUID 是代理键,只是全局唯一的代理。 - Kevin Peno
1
@andrey:一旦选择了特定类型的代理键,更改起来就很困难。我知道我们将有数百万个对所有“账户”的引用,即大型外键会使数据库大小增加很多,需要更多的I/O,读取更多的物理文件块等。优化不一定是过早的。 - plmuon
1
@Andrey,确定数据的正确领域并不是过早优化。字段大小影响:所有I/O、索引大小、数据存储需求、备份;对于任何扫描检索数据,这直接转化为性能,对于查找而言不是直接影响,但仍然会产生影响。 - Unreason
1
@Andrey,只有傻瓜才不会在设计阶段尝试优化数据库。那些认为所有优化都是过早的开发人员设计的数据库,在拥有一亿条记录和从一开始就是错误选择的设计时很难修复。这不是过早的优化,因为这个选择将影响几乎所有查询和性能。 - HLGEM
2
@Andrey,“不会对性能产生太大影响。” - 很好的推理 ;) - Unreason
显示剩余10条评论
1个回答

3
您有些混淆了。
1)关于代理键有两种定义:
代理键(1) 这个定义基于Hall、Owlett和Todd(1976)所给出的定义。 在这里,代理键代表外部世界中的一个实体。代理键由系统内部生成,但对用户或应用程序可见。 代理键(2) 这个定义基于Wieringa和De Jonge(1991)所给出的定义。 在这里,代理键代表数据库本身中的一个对象。代理键由系统内部生成,对用户或应用程序不可见。 代理键(1)的定义是指其在数据模型中的使用,而不是存储模型,并且在本文中使用。请参见Date(1998)。

(来自维基百科关于替代键的条目;阅读文章时要保持一定的怀疑态度——例如引用“替代键比复合键更便宜(需要比较的列更少)”可能在表面上看起来合理,但是自然复合键将创建自然有序和分离的索引,允许在浏览或分析数据时进行非常有效的扫描,同样由于相同的逻辑,返回包含多行的结果集的连接实际上可以执行得更好)

无论如何,在考虑数据模型的角度看待替代键时,您不应该考虑您所谓的“传统”定义。

2) 您认为UUID是自然键的逻辑非常棘手

引用您的问题:

我会将UUID视为自然键,因为它可以像帐户号码一样用于引用特定帐户,以独特且不变的方式。

这不是自然键与替代键的定义或区别特征。自然键具有以下属性(来源于wiki):

自然键是具有逻辑关系的候选键,与该行中的属性有关。自然键有时称为域键。
与没有这种逻辑关系的代理键相比,自然键的主要优点在于它已经存在;不需要向模式添加新的人工列。使用自然键(如果可以识别)还简化了数据质量:它确保只能有一个关键字的行;这个“真相的一个版本”可以得到验证,因为自然键基于现实世界的观察。
通常UUID和同一行的属性之间没有逻辑关系。但是,如果UUID由外部系统分配,并且您已经有将它们存储为属性的要求,则具有该逻辑(类似于您可以考虑序列号或社会安全号码为自然键)。
仅在这个意义上,UUID可能停止成为代理键,但您仍然可能会拥有(并且可能会拥有)另一个候选键的更强大和更丰富的逻辑,用于同一行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接