复合主键

TC.*_*TC. 20 sql database composite primary-key

我正在设计一个数据库,用于存储源自许多不同来源的数据.我存储的实例由原始源分配唯一ID.我存储的每个实例都应包含有关其来源的信息,以及该源关联的ID.

例如,请考虑下表说明问题:

----------------------------------------------------------------
| source_id | id_on_source | data                              |
----------------------------------------------------------------
| 1         | 17600        | ...                               |
| 1         | 17601        | ...                               |
| 2         | 1            | ...                               |
| 3         | 1            | ...                               |
----------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

请注意,虽然id_on_source每个源都是唯一的,但可以id_on_source为不同的源找到相同的源.

我对关系数据库有一个很好的理解,但远非专家甚至是有经验的用户.我在设计中遇到的问题是我应该用作主键的问题.数据似乎决定使用复合主键(source_id, id_on_source).经过一番谷歌搜索后,我发现了一些关于复合主键优缺点的激烈争论,让我有点困惑.

该表与其他表具有一对多的关系,因此将在其他表的外键中引用.

我不依赖于特定的RDBMS,我不知道这是否事项的参数的缘故,但让我们说,我更喜欢的工作SQLiteMySQL.

在这种情况下使用复合外键有哪些优缺点?你更喜欢哪个?

Ste*_*eet 30

我个人觉得复合主键很痛苦.对于您希望加入"sources"表的每个表,您需要添加source_id和id_on_source字段.

我将在您的sources表上创建一个标准的自动递增主键,并在source_id和id_on_source列上添加唯一索引.

然后,这允许您仅将sources表的id添加为其他表上的外键.

通常我也发现在许多框架和工具产品中对复合主键的支持最多是"不完整"而在其他框架中不存在


Eri*_*ric 13

复合键很难管理,加入速度很慢.由于您正在构建汇总表,因此请使用代理键(即自动增量/标识列).留下你的自然键列.

这也有很多其他好处.首先,如果您与公司合并并且他们拥有相同的来源,但重复使用密钥,那么如果您使用代理密钥,则会遇到麻烦.

这是数据仓库中公认的最佳实践(比您正在做的更大的事业,但仍然相关),并且有充分的理由.代理提供数据完整性和快速连接.您可以使用自然键快速刻录,因此请远离它们作为标识符,并且仅在导入过程中使用它们.

  • 你到底在说什么麻烦?如果你在合并上有冲突,你不是可能想要一个错误而不是重复数据吗? (3认同)
  • @displayname复合键的加入速度应该不比代理键快,只要CK被正确编入索引 - 给定PK索引确实索引所有字段我发现Eric的声明很难相信 - 我希望能够定量查看分析查询和基准测试证明CK比SK慢. (3认同)
  • @JeffDavis确切地说,代理键邀请冗余AFAIK. (2认同)

Jef*_*vis 8

您有一个业务要求,即这两个属性的组合是唯一的.所以,你应该UNIQUE对这两个属性有一个约束.无论您将该UNIQUE约束称为"主要"实际上只是一种偏好,除了文档之外它没有太大影响.

唯一的问题是你是否然后添加一个额外的列并标记它UNIQUE.我能看到这样做的唯一原因是性能,这是一个合理的原因.

就个人而言,我不喜欢将每个数据库转换为基本上是图形的方法,其中生成的列本质上是指针,而您只是从一个遍历到下一个.我认为这会抛弃关系系统的所有优点.如果您退一步考虑一下,那么您将引入一堆对您的业务毫无意义的列.您可能对我的相关博客文章感兴趣.


sof*_*eda 6

我相信复合键创建了一个非常自然和描述性的数据模型.我的经验来自Oracle,我不认为在创建复合PK时存在任何技术问题.事实上,任何分析数据字典的人都会立即了解有关该表的内容.在您的情况下,很明显每个source_id必须具有唯一的id_on_source.

自然键的使用经常引发热烈的争论,但是我使用的人就像从良好的数据模型角度看自然键.

  • 点。通常,您会发现主实体将具有数据库生成的唯一密钥。例如带有CustomerId的Customer表。其通常具有辅助键的辅助表具有组合键,并且大多数表都没有FK引用它们。例如,如果您存储客户电话号码的历史记录,则在Customer_contact_history表中,CustomerId,phone,changedate列可能是复合PK,因为这三件事自然是唯一的。 (2认同)