【问题标题】:What is the best way to enforce a "favorite" in a parent child relationship in MySQL?在 MySQL 的父子关系中强制执行“最喜欢”的最佳方法是什么?
【发布时间】:2019-12-14 23:11:40
【问题描述】:

我有一个这样的父子表。

PARENT
id - INT NOT NULL
favoriteChild - NULL DEFAULT NULL

CHILD
id - INT NOT NULL
parent_id - INT NOT NULL

RELATIONSHIPS
parent.favoriteChild -> child.id
child.parent_id -> parent.id

我正在创建一个父母,然后是一个孩子。我有一个触发器设置,以便第一次为给定父级创建子级时,设置 favoriteChild 的值。

保证设置为 favoriteChild 的孩子是父母的孩子的最佳方法是什么?

我的第一反应是使用 BEFORE_INSERT 触发器,以便在修改 favoriteChild 时首先验证它是属于该父母的孩子的身份和 id。

我是否错过了一种更优雅的处理方式?

【问题讨论】:

  • 如果你使用 MySQL 8.0,你可以使用 CHECK 约束。
  • @Barmar - CHECK 约束不能查询其他表。
  • 这是一个常见问题解答。在考虑发布之前,请始终在谷歌上搜索任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有或没有您的特定字符串/名称和站点:stackoverflow.com 和标签,并阅读许多答案。如果您发布问题,请使用一个短语作为标题。请参阅How to Ask 和投票箭头鼠标悬停文本。 PS FK 被称为关系,但是是约束。表格代表关系(船舶)/关联。 FK 约束表示,如果某些值一起参与某个关系/关联,那么它们也会在另一个某个关系/关联中参与一次。
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出(包括逐字错误消息)的示例输入(作为初始化代码);标签和版本;明确的规范和解释。对于包含最少代码的错误,您可以给出的代码是您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)对于包含 DBMS 和 DDL 的 SQL,其中包括约束、索引和表格初始化。
  • parentchild 不应该是单独的表,因为孩子可以有自己的孩子(第一个父母的孙子),所以它应该只是一个 person 表。每个人都应该有mother_idfather_idfavorite_child_idCHECK 约束可以验证这一点。

标签: mysql database foreign-keys


【解决方案1】:
CREATE TABLE PARENT (
  id INT NOT NULL PRIMARY KEY,
  favoriteChild INT NULL DEFAULT NULL
);

CREATE TABLE CHILD (
  id INT NOT NULL PRIMARY KEY,
  parent_id INT NOT NULL,
  UNIQUE KEY (parent_id, id),
  FOREIGN KEY (parent_id) REFERENCES PARENT(id)
);

ALTER TABLE PARENT ADD FOREIGN KEY (id, favoriteChild) 
  REFERENCES CHILD (parent_id, id);

现在我们证明,当我们插入一个父子节点并让该子节点成为其父节点的最爱时,这些约束得到了满足:

mysql> insert into parent values (10, null);
Query OK, 1 row affected (0.00 sec)

mysql> insert into child values (1, 10);
Query OK, 1 row affected (0.00 sec)

mysql> update parent set favoriteChild = 1 where id = 10;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

现在我们尝试另一个父母和孩子,但让孩子引用不同的父母。我们不能让那个孩子成为错误父母的最爱。

mysql> insert into parent values (20, null);
Query OK, 1 row affected (0.00 sec)

mysql> insert into child values (2, 10);
Query OK, 1 row affected (0.00 sec)

mysql> update parent set favoriteChild = 2 where id = 20;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`parent`, CONSTRAINT `parent_ibfk_1` FOREIGN KEY (`id`, `favoriteChild`) REFERENCES `child` (`parent_id`, `id`))

【讨论】:

    猜你喜欢
    • 2021-06-25
    • 1970-01-01
    • 2014-02-28
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 2012-10-02
    • 1970-01-01
    • 2010-12-25
    相关资源
    最近更新 更多