外键关系约束 - 级联更新也是外部id的另一个值

时间:2017-01-11 16:05:50

标签: mysql foreign-keys constraints foreign-key-relationship

INITIAL STATE

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)

我想要的是如果我更新表parent_validity中的parents,则应更新表child_validity中的相关children。我对相关的意思是id s的外键关系。

我的结果是:表parents中的任何有效性更改都会更改表children中的所有有效性

我不想做我需要的PHP。让MySQL处理。

我无法在网络上获取我的请求的正确搜索字词,因此我无法找到任何解决方案。你能帮我吗?

感谢您的帮助。

注意:我认为我的q标题需要更新。 (那是我最好的,对不起。)

我的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;

2 个答案:

答案 0 :(得分:1)

创建约束 CONSTRAINT fk_parent_validity FOREIGN KEY (child_validity) REFERENCES parents(parent_validity) ON UPDATE CASCADE在表之间创建一个新的外键。

当您使用值1更新parent_validity并将其更改为0时,MySQL会使用外键将其级联,以设置值为1的所有引用并更新为0(在本例中为{{ 1}}它原来是1)。

您需要使用UPDATE触发器,而不是外键。触发器是在数据库上发生事件时自动运行的其他过程。你需要一个" UPDATE"触发这里。

认为这可行:

child_validity

我没有多少使用触发器,但希望这些链接能够提供帮助:

http://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html https://www.techonthenet.com/mysql/triggers/after_update.php

答案 1 :(得分:1)

选项是复合键,但您应该评估此解决方案对设计的影响:

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)