MySQL InnoDB 约束不起作用

标签 mysql database foreign-keys constraints innodb

我偶然发现了 innoDB 约束的奇怪行为,但找不到原因。 我有包含数据的表格。
下面列出了它们的结构:


CREATE TABLE `contents` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `title` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `fields` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `type` varchar(45) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `nameUNIQUE` (`name`),
  KEY `name` (`name`),
  KEY `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `dataTable` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `value` double NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `value_UNIQUE` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `content_data` (
  `content_id` int(10) unsigned NOT NULL,
  `field_id` int(10) unsigned NOT NULL,
  `data_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`content_id`,`field_id`,`data_id`),
  KEY `fk_content_data_2_idx` (`field_id`),
  KEY `fk_content_data_3_idx` (`data_id`),
  CONSTRAINT `fk_content_data_1` FOREIGN KEY (`content_id`) REFERENCES `contents` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_content_data_2` FOREIGN KEY (`field_id`) REFERENCES `fields` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_content_data_3` FOREIGN KEY (`data_id`) REFERENCES `dataTable` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

现在,让我们执行两个查询:
第一个查询:


mysql> SELECT * FROM `dataTable` where id=21318;
Empty set (0.00 sec)

我们得到了空集,这没关系,因为 dataTable 实际上没有任何 id=21318 的行
第二个查询:


mysql> SELECT * FROM `content_data` where data_id=21318;
+------------+----------+---------+
| content_id | field_id | data_id |
+------------+----------+---------+
|        552 |       35 |   21318 |
+------------+----------+---------+
1 row in set (0.00 sec)

在这里,最后一个查询给了我们 data_id=21318 的结果。卧槽!


如何解释这种情况?
为什么约束不起作用?
任何想法,谢谢。

最佳答案

如果调用了

SET FOREIGN_KEY_CHECKS=0;

然后 FK 检查被关闭。谁知道呢,这可能就是你系统现在的状态。用

打开它们
SET FOREIGN_KEY_CHECKS=1;

注意以下几点。只是重新打开检查并不会重新验证参照完整性。为此,需要 ALTER TABLE

简单地发布一个架构并不能说明您受到了保护。

意思是,我可以关闭我的约束,使用系统,删除一些数据,执行 LOAD DATA INFILE(简而言之,弄乱我的数据),然后带着模式跑到 Stackoverflow 并说“天哪,这是怎么发生的” .

而且您的系统现在处于什么状态并不重要。重要的是当时的情况。

关于MySQL InnoDB 约束不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36727300/

相关文章:

php - Mysql CURDATE() 两个日期之间

mysql - 两个一对多的关系——每个事件都有很多点,每个点都有很多预订

mysql - sqlite 插入同时删除完整的重复项

mysql - 如何在一个表的单列和第二个表的多行之间创建关系?

python - 我可以使用 SQLAlchemy 有两个外键引用同一个表中的不同记录吗?

php - 如何使用 PHP 将图像名称数组动态存储到数据库中

java - Android 应用程序无法将数据插入 MySQL DB

php - 验证后为什么我的表单数据被清除

database - 为什么使用应用程序生成自定义 uuid 而不是数据库 id?

python - Django admin list_display 使用外键异常缓慢