多对多关系中的重复主键
Posted
技术标签:
【中文标题】多对多关系中的重复主键【英文标题】:Duplicate primary keys in many-to-many relationship 【发布时间】:2020-02-04 05:21:02 【问题描述】:tArticle
和tCustomer
这两个表之间存在 m:n 关系。每当客户购买商品时,商品和客户之间的链接就会存储在第三个表中,其中包含包含客户购买金额的附加属性。
tArticle:
kArticle | title | stock
---------+-------+------
1 | Water | 39
2 | Apple | 14
tCustomer:
kCustomer | surname | firstName
----------+---------+----------
1 | Muller | Max
2 | Meier | Tom
tCustomer_tArticle:
kCustomer | kArticle | number
----------+----------+---------
1 | 2 | 2
2 | 2 | 5
2 | 2 | 3
我知道强烈建议您使用组合外键作为主键。但是因为同一个客户可以两次购买同一篇文章,这将不再是唯一的。
现在我的问题是我需要在第三个表中添加一个AUTO_INCREMENT
主键还是应该使用物理顺序来获得唯一记录。
我的第二个问题是,是否有办法在实体关系图中指定 m:n 关系中的链接是否可能出现两次。
【问题讨论】:
请在每个帖子中问一个问题,并且请不要问重复的问题,正如人们所预料的那样,这些都是重复的。 我认为您应该将此表重命名为 Orders 并添加 auto_increment 主键 - id,这样您的数据库中就可以有另一个需要使用 order_id 的表。 【参考方案1】:“现在我的问题是我需要向第三个表添加一个 AUTO_INCREMENT 主键还是应该使用物理顺序来获得唯一记录。”
“具有唯一记录的物理顺序”是什么意思?
在你的情况下,我建议添加一个 AUTO_INCREMENT PK,比如:
order_id PRIMARY KEY AUTO_INCREMENT
我的理由是: 想想当你去麦当劳时,你会得到一张带有订单 ID 的收据。当您再次购买食物时,您将在新收据上获得不同的订单 ID。因此,order_id 属性使每个订单都是唯一的。
"如果有办法在实体关系图中指定 m:n 关系中的链接是否可能出现两次"
据我所知,没有。我假设您希望您的 E-R 模型反映多少次(或者客户可以多次购买同一商品),如果是这样,您可以按以下方式思考这个问题:
tCustomer_tArticle(order_id, kCustomer, kArticle, number) 能反映这个特性吗?是的。我们可以做到:
SELECT order_id,kCustomer,kArticle,number FROM tCustomer_tArticle WHERE kCustomer="Tom";
这将为我们提供 Tom 下了多少订单的结果。
只要你有一个PK来表明每个订单,你就会得到第二个问题的答案。
【讨论】:
如果我的回答没有解决您的问题,请随时发表评论【参考方案2】:考虑您试图在 tCustomer_tArticle 表中表示哪些信息。例如以下情况:
kCustomer | kArticle | number
----------+----------+---------
2 | 2 | 3
2 | 2 | 3
这只是意味着汤姆买了六个苹果,还是意味着三个苹果各有两笔交易?如果表只是数量的记录,那么可以将kCustomer,kArticle作为key,一行记录相同的信息:
kCustomer | kArticle | number
----------+----------+---------
2 | 2 | 6
如果表应该记录单个事务,那么表中似乎缺少信息。鉴于您的原始示例包含三行样本数据,可能不清楚这是一个、两个还是三个事务。我希望有某种事务标识符作为复合键的一部分。我认为自动递增的数字不会有帮助。在考虑添加代理键之前,您需要先确定对业务领域有意义的有意义的键。
【讨论】:
【参考方案3】:我不知道在哪里“强烈推荐”两个外键作为主键。在适当的情况下,这绝对是一种方法。我更喜欢始终为表分配唯一的自动递增键的方法,除非空间开销是一个大问题。自动递增键提供:
update
s 和 delete
s 对每一行的唯一引用。
广告订单记录。
可以向表声明更简单的外键。
本质上,您的表是一个事务表。我不仅会推荐自动递增的密钥,还会推荐交易日期/时间以及其他信息。
至于这条评论:
或者我应该使用物理订单来获得唯一的记录。
SQL 表代表无序 集合。您应该看到对访问行有用的物理顺序。如果您关心插入顺序,那么您确实需要一个自动递增的键。
【讨论】:
“我不知道在哪里“强烈推荐”两个外键作为主键”这取决于用例,但通常是M: N 对是唯一的,因此即使我们不希望将它们作为主要对象,我们也希望在它们上构建唯一键约束。但似乎 OP 的业务逻辑是不太常见的场景之一。以上是关于多对多关系中的重复主键的主要内容,如果未能解决你的问题,请参考以下文章