只是添加我的解决方案,因为我遇到类似的问题。
TL; DR
- 重新创建具有相同外键规范但名称与表先前所拥有名称不同的表。
- 删除结果表(还将删除原始的孤儿外键)
- 用原始或没有外键重新创建表
详情
我遇到一个令人讨厌的情况,由于未提前删除外键,所以ALTER TABLE语句失败。这导致InnoDB数据字典中出现一些不一致(可能是由于http://bugs.mysql.com/bug.php?id=58215引起的)。
此处相关问题:https : //stackoverflow.com/questions/16857451/error-in-foreign-key-constraint-on-a-droped-table
mysql> ALTER TABLE `visits` CHANGE COLUMN `variation_visitor_id` `variation_visitor_id` INT(11) NOT NULL ;
将'./db/#sql-482c_8448f'重命名为'./db/visits'时出错(错误号:150)
mysql> SHOW ENGINE INNODB STATUS;
Error in foreign key constraint of table db/visits:
FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definitippon.
由于无法恢复要访问的#sql-482c_8448f表,因此我决定从更改之前进行的备份中重新导入该表。但是,这失败了。调查中:
- 该约束已从INFORMATION_SCHEMA.TABLE_CONSTRAINTS和INFORMATION_SCHEMA.STATISTICS中删除
- 但是该约束在INFORMATION_SCHEMA.INNODB_SYS_FOREIGN中仍然可见。
- 该表不存在,所以我无法删除外键
- 我不能没有错误地创建表
SQL /错误
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN WHERE ID='db/fk_visits_variations_visitors1';
+-----------------------------------+-----------+------------------------+--------+------+
| ID | FOR_NAME | REF_NAME | N_COLS | TYPE |
+-----------------------------------+-----------+------------------------+--------+------+
| db/fk_visits_variations_visitors1 | db/visits | db/variations_visitors | 1 | 48 |
+-----------------------------------+-----------+------------------------+--------+------+
尝试重新创建没有外键的表时导致错误150
mysql>
SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `visits` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`variation_visitor_id` INT(11) NOT NULL ,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;
ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 150)
mysql> SHOW ENGINE INNODB STATUS;
Error in foreign key constraint of table db/visits:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
CONSTRAINT "fk_visits_variations_visitors1" FOREIGN KEY ("variation_visitor_id") REFERENCES "variations_visitors" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
尝试创建它导致错误121
mysql>
SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `visits` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`variation_visitor_id` INT(11) NOT NULL ,
PRIMARY KEY (`id`),
KEY `fk_visits_variations_visitors1` (`variation_visitor_id`),
CONSTRAINT `fk_visits_variations_visitors1` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;
ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 121)
mysql> SHOW ENGINE INNODB STATUS;
Error in foreign key constraint creation for table `db`.`visits`.
A foreign key constraint of name `db`.`fk_visits_variations_visitors1`
already exists. (Note that internally InnoDB adds 'databasename'
in front of the user-defined constraint name.)
Note that InnoDB's FOREIGN KEY system tables store
constraint names as case-insensitive, with the
MySQL standard latin1_swedish_ci collation. If you
create tables or databases whose names differ only in
> the character case, then collisions in constraint
names can occur. Workaround: name your constraints
explicitly with unique names.
最终,我使用了新的外键名称。我没想到这会起作用,但是它允许创建表。
mysql>
SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `visits` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`variation_visitor_id` INT(11) NOT NULL ,
PRIMARY KEY (`id`),
KEY `fk_visits_variations_visitors2` (`variation_visitor_id`),
CONSTRAINT `fk_visits_variations_visitors2` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;
之后,只需删除表,即可删除INFORMATION_SCHEMA.INNODB_SYS_FOREIGN中的错误记录,从而允许使用原始外键名称进行导入。
my_user
但该错误与my_db.user
... 有关