[英]MYSQL ERROR 1823 When SET FOREIGN_KEY_CHECKS=1
我有一个奇怪的错误,当 FOREIGN_KEY_CHECKS = 0 和 2 个查询被执行时(除了 FOREIGN_CHECK_CHECKS 外,这两种情况都一样。
该错误导致错误 ERROR 1823 (HY000): Failed to add the foreign key constraint...(完整错误如下)
如果我使用 SET FOREIGN_KEY_CHECKS=1 运行查询,它会按预期工作。 (这几乎似乎是倒叙,因为关闭外键检查应该让事情过去,尽管不应该)
这是mysql中的错误还是我不明白? 我找不到有关此 mysql 错误代码的太多信息。
MYSQL 版本:5.6.33
错误(上次查询):
mysql> SET FOREIGN_KEY_CHECKS=0;
Query OK, 0 rows affected (0.00 sec)
mysql> ALTER TABLE phppos_people ADD INDEX phppos_people_ibfk_1 (image_id);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE phppos_customers ADD CONSTRAINT phppos_customers_ibfk_1 FOREIGN KEY person_id (person_id) REFERENCES phppos_people (person_id) ON UPDATE NO ACTION ON DELETE NO ACTION;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE phppos_employees ADD CONSTRAINT phppos_employees_ibfk_1 FOREIGN KEY person_id (person_id) REFERENCES phppos_people (person_id) ON UPDATE NO ACTION ON DELETE NO ACTION;
ERROR 1823 (HY000): Failed to add the foreign key constraint 'migrate/person_id' to system tables
成功:
mysql> SET FOREIGN_KEY_CHECKS=1;
Query OK, 0 rows affected (0.00 sec)
mysql> ALTER TABLE phppos_people ADD INDEX phppos_people_ibfk_1 (image_id);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE phppos_customers ADD CONSTRAINT phppos_customers_ibfk_1 FOREIGN KEY person_id (person_id) REFERENCES phppos_people (person_id) ON UPDATE NO ACTION ON DELETE NO ACTION;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE phppos_employees ADD CONSTRAINT phppos_employees_ibfk_1 FOREIGN KEY person_id (person_id) REFERENCES phppos_people (person_id) ON UPDATE NO ACTION ON DELETE NO ACTION;
Query OK, 1 row affected (0.04 sec)
Records: 1 Duplicates: 0 Warnings: 0
架构:
mysql> show create table phppos_people;
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_people | CREATE TABLE `phppos_people` (
`first_name` varchar(255) CHARACTER SET ucs2 NOT NULL,
`last_name` varchar(255) CHARACTER SET ucs2 NOT NULL,
`phone_number` varchar(255) CHARACTER SET ucs2 NOT NULL,
`email` varchar(255) CHARACTER SET ucs2 NOT NULL,
`address_1` varchar(255) CHARACTER SET ucs2 NOT NULL,
`address_2` varchar(255) CHARACTER SET ucs2 NOT NULL,
`city` varchar(255) CHARACTER SET ucs2 NOT NULL,
`state` varchar(255) CHARACTER SET ucs2 NOT NULL,
`zip` varchar(255) CHARACTER SET ucs2 NOT NULL,
`country` varchar(255) CHARACTER SET ucs2 NOT NULL,
`comments` text CHARACTER SET ucs2 NOT NULL,
`image_id` int(11) DEFAULT NULL,
`person_id` int(11) NOT NULL,
PRIMARY KEY (`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> show create table phppos_customers;
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_customers | CREATE TABLE `phppos_customers` (
`id` int(11) NOT NULL,
`person_id` int(11) NOT NULL,
`account_number` varchar(255) CHARACTER SET ucs2 DEFAULT NULL,
`override_default_tax` int(11) NOT NULL,
`company_name` varchar(255) CHARACTER SET ucs2 NOT NULL,
`balance` decimal(23,10) NOT NULL,
`credit_limit` decimal(23,10) DEFAULT NULL,
`points` decimal(23,10) NOT NULL,
`current_spend_for_points` decimal(23,10) NOT NULL,
`current_sales_for_discount` int(11) NOT NULL,
`taxable` int(11) NOT NULL,
`tax_certificate` varchar(255) CHARACTER SET ucs2 NOT NULL,
`cc_token` varchar(255) CHARACTER SET ucs2 DEFAULT NULL,
`cc_preview` varchar(255) CHARACTER SET ucs2 DEFAULT NULL,
`card_issuer` varchar(255) CHARACTER SET ucs2 DEFAULT NULL,
`tier_id` int(11) DEFAULT NULL,
`deleted` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
是的,这似乎是一个错误。 我可以在 MySQL 5.6+(以及 MySQL 8 中类似的东西)中验证它,而 5.5 不受影响。 这里的问题是 MySQL 使用哪个约束名称。
在语法中
[CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name, ...) REFERENCES tbl_name (index_col_name,...)
约束名称应该是符号,或者如果没有给出,则自动创建:
如果给出了 CONSTRAINT 符号子句,则符号值(如果使用)在数据库中必须是唯一的。 重复的符号将导致类似于以下内容的错误: ERROR 1022 (2300): Can't write; 表“#sql-464_1”中的重复键。 如果没有给出子句,或者在 CONSTRAINT 关键字后面没有包含符号,则会自动为约束创建一个名称。
这通常会像这样工作:
如果禁用FOREIGN_KEY_CHECKS
,对于ALTER TABLE
而不是CREATE TABLE
,它将额外使用index_name :
因此,虽然每个表的index_name通常必须是唯一的,但在这里,您的两个ALTER
语句中的公共index_name person_id
会引起麻烦,因为 MySQL 试图创建两个具有相同(错误)名称的约束。
作为一种解决方法,在您的情况下,您可以从您的更改语句中删除index_name person_id
,因为索引,如果一切正常,无论如何都应该获得符号给出的名称:
如果子表上已经存在可以支持外键的显式定义的索引,则忽略 index_name 值。 否则,MySQL 会隐式创建根据以下规则命名的外键索引:
如果已定义,则使用 CONSTRAINT 符号值。 否则,使用 FOREIGN KEY index_name 值。
如果 CONSTRAINT 符号或 FOREIGN KEY index_name 均未定义,则使用引用外键列的名称生成外键索引名称。
如果要显式命名索引,但使用默认约束名称,则可以在添加外键之前添加索引,例如使用
ALTER TABLE phppos_customers ADD INDEX person_id (person_id);
ALTER TABLE phppos_customers ADD CONSTRAINT FOREIGN KEY (person_id) REFERENCES ...
MySQL 8 显示了一个稍微不同的行为(当FOREIGN_KEY_CHECKS
被禁用并且仅用于ALTER TABLE
):它也错误地使用了index_name ,但前提是没有给出符号- 在你的情况下会起作用,因为你设置了符号。
得到相同的错误编号:1823; 符号:ER_FK_FAIL_ADD_SYSTEM; SQLSTATE: HY00063 消息:未能将外键约束“%s”添加到系统表
在我的情况下,当我减少查询工作的约束名称的长度时,FK 名称太长。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.