MySQL默认情况下FORIEGN_KEY_CHECKS=1,但无效。

15 浏览
0 Comments

MySQL默认情况下FORIEGN_KEY_CHECKS=1,但无效。

在MySQL Ver 14.14 Distrib 5.7.25上,对于Linux(x86_64)来说,默认设置@@GLOBAL.foreign_key_checks=1似乎不起作用,因为我尝试插入一行包含父表键中不存在的值的数据,插入操作竟然成功了。

为什么我必须执行SET FOREIGN_KEY_CHECKS=1,即使默认情况下已经设置了foreign_key_checks=1

例如,我有一个表如下:

mysql> SHOW CREATE TABLE score\G
*************************** 1. row ***************************
       Table: score
Create Table: CREATE TABLE `score` (
  `student_id` int(10) unsigned NOT NULL,
  `event_id` int(10) unsigned NOT NULL,
  `score` int(11) NOT NULL,
  PRIMARY KEY (`event_id`,`student_id`),
  KEY `student_id` (`student_id`),
  CONSTRAINT `fk_event_id` FOREIGN KEY (`event_id`) REFERENCES `grace_event` (`event_id`) ON UPDATE CASCADE,
  CONSTRAINT `fk_student_id` FOREIGN KEY (`student_id`) REFERENCES `student` (`student_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)

...我输入mysql> INSERT INTO score (event_id,student_id,score) VALUES(9999,9999,0);然后得到了如下结果...

Query OK, 1 row affected (0.01 sec)

所以,为了弄清楚为什么这个插入操作在不应该成功的情况下却成功了,我阅读了以下网页...

...但是其中没有一个解释了为什么这个插入操作成功了(不幸的是)。

我确保我三个表的以下条件都满足:

  • 外键必须是INT UNSIGNED。是的。
  • 默认存储引擎必须是InnoDB。是的。
  • 对于每个外键声明,使用ON UPDATE CASCADE。是的。
  • phpmyadmin显示foreign key checks设置为ON。是的。

...并且SELECT @@GLOBAL.foreign_key_checks显示...

mysql> SELECT @@GLOBAL.foreign_key_checks;
+-----------------------------+
| @@GLOBAL.foreign_key_checks |
+-----------------------------+
|                           1 |
+-----------------------------+

在上述所有设置的情况下,mysql> INSERT INTO score (event_id,student_id,score) VALUES(9999,9999,0);仍然成功了。

直到我执行了SET FOREIGN_KEY_CHECKS=1INSERT才最终失败了...

ERROR 1452 (23000): Cannot add or update a child row: a foreign key

constraint fails (sampdb.score, CONSTRAINT fk_event_id FOREIGN

KEY (event_id) REFERENCES grace_event (event_id) ON UPDATE

CASCADE)

为什么我在默认情况下(显然)已经设置为1的情况下,仍然需要执行SET FOREIGN_KEY_CHECKS=1默认的@@GLOBAL.foreign_key_checks设置没有起作用吗?这是一个bug吗?

0
0 Comments

问题出现的原因是在执行插入操作时,外键约束检查失败。解决方法是将foreign_key_checks设置为1。

文章内容如下:

MySQL默认情况下,foreign_key_checks的值为1,但是在某些情况下可能会出现无法正常工作的情况。下面是一个例子:

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.25    |
+-----------+
1 row in set (0.00 sec)
mysql> SELECT @.foreign_key_checks, @.foreign_key_checks;
+-----------------------------+------------------------------+
| @.foreign_key_checks | @.foreign_key_checks |
+-----------------------------+------------------------------+
|                           1 |                            1 |
+-----------------------------+------------------------------+
1 row in set (0.00 sec)
mysql> DROP TABLE IF EXISTS `student`, `grace_event`, `score`;
Query OK, 0 rows affected, 3 warnings (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `student` (
    ->   `student_id` int(10) unsigned NOT NULL PRIMARY KEY
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `grace_event` (
    ->   `grace_event` int(10) unsigned NOT NULL PRIMARY KEY
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `score` (
    ->   `student_id` int(10) unsigned NOT NULL,
    ->   `event_id` int(10) unsigned NOT NULL,
    ->   `score` int(11) NOT NULL,
    ->   PRIMARY KEY (`event_id`,`student_id`),
    ->   KEY `student_id` (`student_id`),
    ->   CONSTRAINT `fk_event_id` FOREIGN KEY (`event_id`)
    ->     REFERENCES `grace_event` (`grace_event`) ON UPDATE CASCADE,
    ->   CONSTRAINT `fk_student_id` FOREIGN KEY (`student_id`)
    ->     REFERENCES `student` (`student_id`) ON UPDATE CASCADE
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `score`
    ->   (`event_id`, `student_id`, `score`)
    -> VALUES
    ->   (9999, 9999, 0);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key
                    constraint fails (`test`.`score`, CONSTRAINT
                    `fk_event_id` FOREIGN KEY (`event_id`) REFERENCES
                    `grace_event` (`grace_event`) ON UPDATE CASCADE)

在上述例子中,当我们执行插入操作时,出现了外键约束检查失败的错误。我们尝试了将foreign_key_checks设置为1,但是问题仍然存在。

经过一番探索,我们发现了解决方法。我们可以通过将foreign_key_checks设置为1来解决这个问题。

希望这篇文章对你有所帮助!

0