首先,如果这是一个骗局,我深表歉意 - 我怀疑它可能是,但我找不到它。
假设我有一张公司表:
id | company_name
----+--------------
1 | Someone
2 | Someone else
...和联系人表:
id | company_id | contact_name | is_primary
----+------------+--------------+------------
1 | 1 | Tom | 1
2 | 2 | Dick | 1
3 | 1 | Harry | 0
4 | 1 | Bob | 0
是否可以设置 contacts
表,使其要求只有一条记录具有 is_primary
标志为每个常见的 company_id
设置?
所以如果我尝试这样做:
UPDATE contacts
SET is_primary = 1
WHERE id = 4
...查询将失败,因为 Tom
(id = 1
) 已被标记为 company_id = 1
的主要联系人.或者甚至更好,是否可以构造一个触发器以便查询成功,但 Tom
的 is_primary
标志会被相同的操作清除?
我不太关心检查 companies
表中是否存在 company_id
,我的 PHP 代码在我到达这个阶段之前就已经执行了这个检查(尽管如果有一种方法可以在同一操作中执行此操作,我想这会很好)。
当我最初想到这个时,我认为“这很容易,我只需在 company_id
和 is_primary
列中添加一个唯一索引”,但显然我赢了' 工作,因为它会将我限制为一个主要联系人和一个非主要联系人 - 任何添加第三个联系人的尝试都会失败。但我不禁觉得会有一种方法可以配置一个唯一索引,该索引为我提供所需的最低功能——拒绝添加第二个主要联系人的尝试,或拒绝离开没有主要联系人的公司的尝试。
我知道我可以将 primary_contact
字段添加到 companies
表,并在 contacts
表中添加 FK,但感觉很乱.我不喜欢两个表都有 FK 到另一个的想法 - 在我看来,一个表应该依赖另一个,而不是两个表相互依赖。我想我只是认为随着时间的推移,出现问题的可能性会增加。
总结:
- 如何限制联系人表,以便只有一条具有给定
company_id
的记录设置了is_primary
标志? - 有人想知道两个表之间有 FK 是好是坏吗?
最佳答案
表格之间的循环引用确实很乱。请参阅这篇(十年前的)文章:SQL By Design: The Circular Reference
进行这种约束的最简洁的方法是添加另一个表:
Company_PrimaryContact
----------------------
company_id
contact_id
PRIMARY KEY (company_id)
FOREIGN KEY (company_id, contact_id)
REFERENCES Contact (company_id, id)
这还需要 UNIQUE
表中的约束 Contact
在 (company_id, id)
关于mysql - 允许/要求只有一个具有共同 FK 的记录具有 "primary"标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9326606/