外键关系约束 - 级联更新还有外键的其他值
foreign key relation constraint - cascade on update also the other value of the foreign id
初始状态
parents
id parent_validity
1 1
2 1
children
id parent_id child_validity
1 1 1
2 1 1
3 2 1
更新后需要的状态
parents
id parent_validity
1 0 (updated as 0)
2 1
children
id parent_id child_validity
1 1 0 (This val is expected as 0)
2 1 0 (This val is expected as 0)
3 2 1 (This val is expected as no change)
我得到了什么
children
id parent_id child_validity
1 1 0
2 1 0
3 2 0 (all values under this column became 0)
我想要的是,如果我在tableparents
中更新一个parent_validity
,那么在tablechildren
中相关的child_validity
应该是更新。 related 的意思是 id
s.
的外键关系
我的结果是:table parents
中的任何有效性更改都会更改 table children
中的所有有效性。
我不想用 PHP 做我要求的事情。让 MySQL 处理。
我无法在网络上为我的请求获得正确的搜索词,因此我无法找到任何解决方案。你能帮帮我吗
感谢您的帮助。
注意:我认为我的 q 标题需要更新。 (那是我最好的,抱歉。)
my sql 创建并给出约束
CREATE TABLE `parents` (
`id` int(2) unsigned NOT NULL AUTO_INCREMENT,
`parent_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
PRIMARY KEY (`id`),
KEY (`parent_validity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `children` (
`id` int(2) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(2) unsigned NOT NULL,
`child_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
PRIMARY KEY (`id`),
KEY (`child_validity`),
CONSTRAINT fk_parent_id FOREIGN KEY (parent_id) REFERENCES parents(id) ON UPDATE CASCADE,
CONSTRAINT fk_parent_validity FOREIGN KEY (child_validity) REFERENCES parents(parent_validity) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
正在创建约束
CONSTRAINT fk_parent_validity FOREIGN KEY (child_validity) REFERENCES parents(parent_validity) ON UPDATE CASCADE
在您的表之间创建一个新的外键。
当您使用值 1 更新 parent_validity
并将其更改为 0 时,MySQL 将其与外键级联以设置值为 1 的所有引用并更新为 0 (在这种情况下,所有 child_validity
原来是 1).
您需要使用更新触发器而不是外键。触发器是附加程序,当数据库上发生事件时,它会自动 运行。这里需要一个 "UPDATE" 触发器。
认为这可能有效:
CREATE TRIGGER update_child_validitiy AFTER UPDATE ON parents
FOR EACH ROW
BEGIN
UPDATE children SET child_validity = NEW.parent_validity WHERE id = NEW.id;
END;
我没有经常使用触发器,但希望这些链接能有所帮助:
http://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html
https://www.techonthenet.com/mysql/triggers/after_update.php
选项是复合键,但您应该评估这对您的解决方案的设计影响:
mysql> DROP TABLE IF EXISTS `children`, `parents`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `parents` (
-> `id` int(2) unsigned NOT NULL AUTO_INCREMENT,
-> `parent_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
-> PRIMARY KEY (`id`, `parent_validity`)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `children` (
-> `id` int(2) unsigned NOT NULL AUTO_INCREMENT,
-> `parent_id` int(2) unsigned NOT NULL,
-> `child_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
-> PRIMARY KEY (`id`),
-> KEY (`parent_id`, `child_validity`),
-> CONSTRAINT `fk_parent_id_child_validity` FOREIGN KEY (`parent_id`, `child_validity`)
-> REFERENCES `parents` (`id`, `parent_validity`) ON UPDATE CASCADE
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO
-> `parents`
-> VALUES
-> (NULL, 1), (NULL, 1);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> INSERT INTO
-> `children`
-> VALUES
-> (NULL, 1, 1),
-> (NULL, 1, 1),
-> (NULL, 2, 1);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT
-> `id`,
-> CONVERT(`parent_validity`, UNSIGNED) `parent_validity`
-> FROM
-> `parents`;
+----+-----------------+
| id | parent_validity |
+----+-----------------+
| 1 | 1 |
| 2 | 1 |
+----+-----------------+
2 rows in set (0.00 sec)
mysql> SELECT
-> `id`,
-> `parent_id`,
-> CONVERT(`child_validity`, UNSIGNED) `child_validity`
-> FROM
-> `children`;
+----+-----------+----------------+
| id | parent_id | child_validity |
+----+-----------+----------------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 1 |
+----+-----------+----------------+
3 rows in set (0.00 sec)
mysql> UPDATE `parents`
-> SET `parent_validity` = 0
-> WHERE `id` = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT
-> `id`,
-> CONVERT(`parent_validity`, UNSIGNED) `parent_validity`
-> FROM
-> `parents`;
+----+-----------------+
| id | parent_validity |
+----+-----------------+
| 1 | 0 |
| 2 | 1 |
+----+-----------------+
2 rows in set (0.00 sec)
mysql> SELECT
-> `id`,
-> `parent_id`,
-> CONVERT(`child_validity`, UNSIGNED) `child_validity`
-> FROM
-> `children`;
+----+-----------+----------------+
| id | parent_id | child_validity |
+----+-----------+----------------+
| 1 | 1 | 0 |
| 2 | 1 | 0 |
| 3 | 2 | 1 |
+----+-----------+----------------+
3 rows in set (0.00 sec)
初始状态
parents
id parent_validity
1 1
2 1
children
id parent_id child_validity
1 1 1
2 1 1
3 2 1
更新后需要的状态
parents
id parent_validity
1 0 (updated as 0)
2 1
children
id parent_id child_validity
1 1 0 (This val is expected as 0)
2 1 0 (This val is expected as 0)
3 2 1 (This val is expected as no change)
我得到了什么
children
id parent_id child_validity
1 1 0
2 1 0
3 2 0 (all values under this column became 0)
我想要的是,如果我在tableparents
中更新一个parent_validity
,那么在tablechildren
中相关的child_validity
应该是更新。 related 的意思是 id
s.
我的结果是:table parents
中的任何有效性更改都会更改 table children
中的所有有效性。
我不想用 PHP 做我要求的事情。让 MySQL 处理。
我无法在网络上为我的请求获得正确的搜索词,因此我无法找到任何解决方案。你能帮帮我吗
感谢您的帮助。
注意:我认为我的 q 标题需要更新。 (那是我最好的,抱歉。)
my sql 创建并给出约束
CREATE TABLE `parents` (
`id` int(2) unsigned NOT NULL AUTO_INCREMENT,
`parent_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
PRIMARY KEY (`id`),
KEY (`parent_validity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `children` (
`id` int(2) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(2) unsigned NOT NULL,
`child_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
PRIMARY KEY (`id`),
KEY (`child_validity`),
CONSTRAINT fk_parent_id FOREIGN KEY (parent_id) REFERENCES parents(id) ON UPDATE CASCADE,
CONSTRAINT fk_parent_validity FOREIGN KEY (child_validity) REFERENCES parents(parent_validity) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
正在创建约束
CONSTRAINT fk_parent_validity FOREIGN KEY (child_validity) REFERENCES parents(parent_validity) ON UPDATE CASCADE
在您的表之间创建一个新的外键。
当您使用值 1 更新 parent_validity
并将其更改为 0 时,MySQL 将其与外键级联以设置值为 1 的所有引用并更新为 0 (在这种情况下,所有 child_validity
原来是 1).
您需要使用更新触发器而不是外键。触发器是附加程序,当数据库上发生事件时,它会自动 运行。这里需要一个 "UPDATE" 触发器。
认为这可能有效:
CREATE TRIGGER update_child_validitiy AFTER UPDATE ON parents
FOR EACH ROW
BEGIN
UPDATE children SET child_validity = NEW.parent_validity WHERE id = NEW.id;
END;
我没有经常使用触发器,但希望这些链接能有所帮助:
http://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html https://www.techonthenet.com/mysql/triggers/after_update.php
选项是复合键,但您应该评估这对您的解决方案的设计影响:
mysql> DROP TABLE IF EXISTS `children`, `parents`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `parents` (
-> `id` int(2) unsigned NOT NULL AUTO_INCREMENT,
-> `parent_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
-> PRIMARY KEY (`id`, `parent_validity`)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `children` (
-> `id` int(2) unsigned NOT NULL AUTO_INCREMENT,
-> `parent_id` int(2) unsigned NOT NULL,
-> `child_validity` bit(1) NOT NULL COMMENT '1:valid or 0:invalid',
-> PRIMARY KEY (`id`),
-> KEY (`parent_id`, `child_validity`),
-> CONSTRAINT `fk_parent_id_child_validity` FOREIGN KEY (`parent_id`, `child_validity`)
-> REFERENCES `parents` (`id`, `parent_validity`) ON UPDATE CASCADE
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO
-> `parents`
-> VALUES
-> (NULL, 1), (NULL, 1);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> INSERT INTO
-> `children`
-> VALUES
-> (NULL, 1, 1),
-> (NULL, 1, 1),
-> (NULL, 2, 1);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT
-> `id`,
-> CONVERT(`parent_validity`, UNSIGNED) `parent_validity`
-> FROM
-> `parents`;
+----+-----------------+
| id | parent_validity |
+----+-----------------+
| 1 | 1 |
| 2 | 1 |
+----+-----------------+
2 rows in set (0.00 sec)
mysql> SELECT
-> `id`,
-> `parent_id`,
-> CONVERT(`child_validity`, UNSIGNED) `child_validity`
-> FROM
-> `children`;
+----+-----------+----------------+
| id | parent_id | child_validity |
+----+-----------+----------------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 1 |
+----+-----------+----------------+
3 rows in set (0.00 sec)
mysql> UPDATE `parents`
-> SET `parent_validity` = 0
-> WHERE `id` = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT
-> `id`,
-> CONVERT(`parent_validity`, UNSIGNED) `parent_validity`
-> FROM
-> `parents`;
+----+-----------------+
| id | parent_validity |
+----+-----------------+
| 1 | 0 |
| 2 | 1 |
+----+-----------------+
2 rows in set (0.00 sec)
mysql> SELECT
-> `id`,
-> `parent_id`,
-> CONVERT(`child_validity`, UNSIGNED) `child_validity`
-> FROM
-> `children`;
+----+-----------+----------------+
| id | parent_id | child_validity |
+----+-----------+----------------+
| 1 | 1 | 0 |
| 2 | 1 | 0 |
| 3 | 2 | 1 |
+----+-----------+----------------+
3 rows in set (0.00 sec)