【发布时间】:2011-05-16 13:45:57
【问题描述】:
我在choosing a primary key找到了这份阅读材料。
- 是否有关于如何为给定表选择主键的指南/博客文章?
- 我应该使用自动递增/生成的键,还是应该将主键基于正在建模的数据(假设它具有真正唯一的字段)?
- 为了性能起见,主键是否应该总是很长,或者我可以将外部唯一 id 作为主键,即使它是一个字符串?
【问题讨论】:
标签: sql mysql database primary-key
我在choosing a primary key找到了这份阅读材料。
【问题讨论】:
标签: sql mysql database primary-key
我使用代理键,通常称为无意义键,由自动生成的 int/bigint 数据类型组成。
以下是我喜欢使用这些键的一些原因。
【讨论】:
键是一组具有两个基本特征的属性:唯一性和最小性。最小性意味着键只有确保唯一性所需的最少属性数。
通常使用三个标准作为选择好键的指南:
这些是很好的指导方针,但不是绝对要求。在所有情况下,功能需求和数据完整性需求都应确定使用哪些密钥。
【讨论】:
我相信在实践中使用natural key 很少比surrogate key 好。
以下是使用自然键作为主键的主要缺点:
您可能有一个不正确的键值,或者您可能只是想重命名一个键值。要对其进行编辑,您必须更新所有将其用作外键的表。
通常很难拥有真正的unique 自然键。
自然键通常是字符串。数字字段上的索引将比字符串字段上的索引更紧凑。
对于主键的数据类型应该是什么没有硬性规定。数字键通常性能更好,但您可以使用字符串,尤其是在表不大且引用它的表也不大的情况下。
【讨论】:
我总是选择 uuid 作为主键。与 int/long key 相比,有一点点开销,但有很多好处:不会遇到类型溢出,以后可以在不更改主键的情况下对数据库进行分片,可以与其他系统集成并确保你的主键总是唯一的,uuid 不能被猜到等等。
【讨论】:
我曾在专业系统(主要是银行软件)中使用过许多不同的数据模型,并且有不同的解决方案。有我见过的 GUID 解决方案,它似乎并没有对性能产生太大影响。我已经看到“服务提供的号码作为系统范围的唯一号码”。我已经看到提供类似 GUID 的算法“但更短”。我还看到使用了业务密钥(如帐号),这是糟糕的设计并导致了问题,我不会推荐它。我已经看到每个表的自动递增键。
我最喜欢什么?服务提供的号码作为系统范围的号码。它运作良好。并且使用简单的键转换表,可以使用用户键(如帐号)找出唯一编号和数据对象类型(不一定是表,因为如果一个数据对象,相同的唯一键可能适用于多个表根据其类型分为不同的表)。
那么有博客之类的吗?好吧,我有一本值得推荐的书,名为 Graeme Simsion 和 Graham Witt 的《数据建模要点》。他们可能不会建议我首选的解决方案,但他们提供了许多真实的示例,并展示了可能的不同类型的解决方案。
【讨论】: