mysql - 允许/要求只有一个具有共同 FK 的记录具有 "primary"标志

标签 mysql triggers unique-index

首先,如果这是一个骗局,我深表歉意 - 我怀疑它可能是,但我找不到它。

假设我有一张公司表:

 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 的主要联系人.或者甚至更好,是否可以构造一个触发器以便查询成功,但 Tomis_primary 标志会被相同的操作清除?

我不太关心检查 companies 表中是否存在 company_id,我的 PHP 代码在我到达这个阶段之前就已经执行了这个检查(尽管如果有一种方法可以在同一操作中执行此操作,我想这会很好)。

当我最初想到这个时,我认为“这很容易,我只需在 company_idis_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/

相关文章:

mysql - 防止 Workbench 自动插入表列

mysql - 向大表添加列 : datatype or INT or reference table?

wpf - 在 WPF 中的 Window.Resources 中声明 EventTrigger 时不起作用

mysql - 2张表的主键

ruby-on-rails - 在 Rails 中同时进行数据库级别和代码级别唯一性验证的目的是什么?

mysql - 插入时重复记录

mysql - SQL查询不返回表中的非唯一值

mysql - 如何根据公式填充 mysql 列值?

mysql - PHP/MySQL 如何触发给客户的短信或邮件

sql - 更新与唯一索引冲突的多行