Как удалить ограничение потерянного внешнего ключа в MySQL?
Использование MySQL 5.5. У меня есть таблица, для которой я не могу добавить внешний ключ:
ALTER TABLE `SOURCE_TABLE`
ADD CONSTRAINT `ConstraintFK`
FOREIGN KEY (`otherTableID`)
REFERENCES `OTHER_TABLE` (`id`)
ON DELETE SET NULL
ON UPDATE CASCADE;
MySQL возвращает следующую ошибку:
Error Code: 1005. Can't create table 'my_schema.#sql-4c0c_b6fc8ca' (errno: 121)
Смотря наSHOW ENGINE INNODB STATUS
Я получил:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
220523 16:34:36 Error in foreign key constraint creation for table `my_schema`.`#sql-4c0c_b6fc8ca`.
A foreign key constraint of name `my_schema`.`ConstraintFK`
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.
Конечно, в этой схеме не определено ограничение с именем ConstraintFK. Я проверил и информационную схему, иSHOW CREATE TABLE SOURCE_TABLE
выход. Последнее показывает, что индекс внешнего ключа существует, но ограничения внешнего ключа, похоже, там нет:
-- only relevant info shown
CREATE TABLE `SOURCE_TABLE` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`otherTableID` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ConstraintFK_idx` (`otherTableID`)
) ENGINE=InnoDB AUTO_INCREMENT=4089 DEFAULT CHARSET=utf8;
CREATE TABLE `OTHER_TABLE` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=58108 DEFAULT CHARSET=utf8;
Действительно, если я попытаюсь снять это ограничение:
ALTER TABLE `SOURCE_TABLE`
DROP FOREIGN KEY `ConstraintFK`;
Я получил:
Error Code: 1025. Error on rename of './my_schema/SOURCE_TABLE' to './my_schema/#sql2-4c0c-b6fc8ca' (errno: 152)
Я посмотрел файловую систему и не вижу причин, по которым переименование таблицы должно завершиться неудачей.
К сожалению, попытка запросить информационную схему не помогает:
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND information_schema.TABLE_CONSTRAINTS.CONSTRAINT_NAME = 'ConstraintFK';
возвращает пустой набор, а:
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND information_schema.TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA = 'my_schema';
возвращает все ограничения внешнего ключа в my_schema, которые я также могу получить изSHOW CREATE TABLE
заявлений, но никаких признаков ConstraintFK...
Глядя на this и this , я подозреваю, что что-то произошло в прошлом, что привело к тому, что этот внешний ключ стал осиротевшим: действительно, этот SOURCE_TABLE был переименован некоторое время назад, и я почти уверен, что внешний ключ, который я пытаюсь добавить, был там в прошлое. Предлагаемый обходной путь — удалить схему и создать ее заново из файла дампа. Могу ли я попробовать что-нибудь еще, что не связано с удалением этой схемы? Это довольно огромно, и время простоя будет иметь значение.