我正在尝试添加外键约束,但失败了:
mysql> alter table order_info add constraint FKlnh846un1oe6hnwkqf5ovtjwo
foreign key (orderId) references orders (orderId);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`storefront`.`#sql-1601_28`, CONSTRAINT `FKlnh846un1oe6hnwkqf5ovtjwo`
FOREIGN KEY (`orderId`) REFERENCES `orders` (`orderId`))
mysql> show create table orders;
| orders | CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`amount` float NOT NULL,
`couponCode` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`createdAt` datetime DEFAULT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`orderId` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`phone` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`status` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`updatedAt` datetime DEFAULT NULL,
`address_id` int(11) DEFAULT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT '0',
`pGateway` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'PAYU',
PRIMARY KEY (`id`),
UNIQUE KEY `UK_9erxssgysqmn8axwyq4er6hen` (`orderId`),
KEY `FKf5464gxwc32ongdvka2rtvw96` (`address_id`),
KEY `email_status_index` (`email`,`status`),
KEY `createdAt_index` (`createdAt`),
KEY `status_index` (`status`),
CONSTRAINT `FKf5464gxwc32ongdvka2rtvw96` FOREIGN KEY (`address_id`) REFERENCES `address` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2961655 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
mysql> show create table order_info;
| order_info | CREATE TABLE `order_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`createdAt` datetime DEFAULT NULL,
`orderId` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`packageId` int(11) NOT NULL,
`updatedAt` datetime DEFAULT NULL,
`amount` int(11) NOT NULL,
`status` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`expiry` datetime DEFAULT NULL,
`child_id` int(11) DEFAULT NULL,
`parent_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1916085 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
mysql> select count(*) from orders;
+----------+
| count(*) |
+----------+
| 2773095 |
+----------+
1 row in set (0.69 sec)
mysql> select count(*) from order_info;
+----------+
| count(*) |
+----------+
| 1914367 |
+----------+
1 row in set (0.61 sec)
mysql> select orderId from order_info where orderId not in (select orderId from orders);
Empty set (5.07 sec)
mysql> select count(*) from order_info where orderId is null;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.63 sec)
现在,两个表都有数据了。不存在订单表中不存在的订单 ID。两列的数据类型相同。那么为什么这会出错呢?究竟违反了什么? 虽然我可以将外键检查设置为 false,然后创建 key ,但我想知道为什么此约束失败。
编辑: 添加了最后一个查询以验证要成为外键的列没有空值。
最佳答案
看起来查询:
从 order_info 中选择 orderId,其中 orderId 不在(从订单中选择 orderId)
不是了解错误数据点的最佳候选者。正如 @paul-spiegel 的建议,NOT EXISTS
更好。这是查询输出:
mysql> select count(*) from order_info oi where not exists
( select null from orders o where o.orderId = oi.orderId);
+----------+
| count(*) |
+----------+
| 6 |
+----------+
1 row in set (31.27 sec)
order_info
中有 6 行的 orderId 在 orders
表中不存在。
NOT EXISTS 的文档:https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
关于mysql - 无法添加或更新子行: a foreign key constraint fails while data exists,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54783996/