MySQL.Не удается создать таблицу errno 150
-
20-09-2019 - |
Вопрос
Я должен создать базу данных с двумя таблицами в MySQL, но скрипт завершается с ошибкой 150 (проблема с внешним ключом).Я дважды проверил, чтобы поля внешнего ключа были одинаковыми в обеих таблицах, и я не могу найти никакой ошибки.
Вот сценарий:
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
DROP SCHEMA IF EXISTS `testdb`;
CREATE SCHEMA IF NOT EXISTS `testdb` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
USE `testdb`;
DROP TABLE IF EXISTS `testdb`.`table1` ;
CREATE TABLE IF NOT EXISTS `testdb`.`table1` (
`id` INT UNSIGNED NOT NULL ,
`field1` VARCHAR(50) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
DROP TABLE IF EXISTS `testdb`.`table2` ;
CREATE TABLE IF NOT EXISTS `testdb`.`table2` (
`id` INT NOT NULL AUTO_INCREMENT ,
`field1` VARCHAR(50) NULL ,
`date` DATE NULL ,
`cnt` INT NULL ,
PRIMARY KEY (`id`) ,
INDEX `FK_table2_table1` (`field1` ASC) ,
CONSTRAINT `FK_table2_table1`
FOREIGN KEY (`field1`)
REFERENCES `testdb`.`table1` (`field1` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
Я пробовал это в Windows и Ubuntu с разными версиями MySQL и не сработало.
Есть какие-нибудь идеи?
Решение
table1.field1
на нем не определен индекс.
Требуется разместить FOREIGN KEY
ограничение на field1
.
С этим:
CREATE TABLE IF NOT EXISTS `testdb`.`table1` (
`id` INT UNSIGNED NOT NULL ,
`field1` VARCHAR(50) NULL ,
KEY ix_table1_field1 (field1),
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
Затем все должно работать так, как ожидалось.
Другие советы
Работая с MySQL Workbench и MySQL 5.5.27, я столкнулся с аналогичной проблемой.В моем случае проблема была с полями типа INT.Ошибочно в одной таблице это было значение INT БЕЗ знака, а в таблице ссылок это было значение INT.
В зависимости от версии MySQL вам может потребоваться сначала создать индекс в table1.field1.
Один из ответов здесь предлагает отключить проверку целостности внешнего ключа.Это ПЛОХАЯ идея.Здесь есть два вероятных виновника:
- Несоответствие типа данных между ссылочным первичным ключом и ссылающимся внешним ключом
- Индексы.Любые внешние ключи, которые вы индексируете, должны быть НЕ НУЛЕВЫМИ
Еще один намек:
Даже когда ваши типы данных кажутся одинаковыми - в моем случае оба столбца имели VARCHAR(50)
- этого недостаточно.
Вам также необходимо убедиться, что оба столбца имеют одинаковый COLLATION
.
Еще одна причина, хотя и немного похожая на другие:Я имел в виду таблицу, в которой, как оказалось, был движок MyISAM вместо InnoDB.
MySQL также выдаст эту ошибку, если вы неправильно введете имя ссылающейся таблицы.Некоторое время я рвала на себе волосы , пока не поняла , что пропустила букву в foreign key (column1) references mistyped_table(column1)
Одним из вариантов (в зависимости от конкретного случая) было бы отключить проверку целостности MySQL:
SET FOREIGN_KEY_CHECKS = 0;
Если ничего не работает, попробуйте это:
Имя внешнего ключа является дубликатом уже существующего ключа.Убедитесь, что имя вашего внешнего ключа уникально в вашей базе данных.Просто добавьте несколько случайных символов в конец имени вашего ключа, чтобы проверить это.
В моем случае одна таблица использовала ограничения внешнего ключа для другой таблицы, которая еще не существовала.Это происходило из-за большого файла makefile, так что это было не так очевидно, как я ожидал.
На случай, если у кого-то все еще возникают проблемы с этим, я перепробовал все решения выше (за исключением SET FOREIGN_KEY_CHECKS) и ничего не сработало.Проблема заключалась в том, что при обращении к первой таблице некоторые базы данных учитывают регистр имен таблиц.Я думаю, это странно, так как я никогда раньше не видел этого в MySQL, Oracle, а теперь это случилось со мной на MariaDB.
Например:
Создайте таблицу, если не существует CADASTRO_MAQUINAS ( Идентификатор переменной(16), Первичный ключ (Id) );
Создать таблицу, если информация не существует ( Параметр Id_Maquina VARCHAR(16) НЕ равен НУЛЮ, ОГРАНИЧЕНИЕ FK_infos_cadastro_maquinas Внешний ключ (Id_Maquina) ссылается на кадастровый номер (Id) );
Если я попытаюсь создать вторую таблицу, используя cadastro_maquinas (строчные буквы) вместо CADASTRO_MAQUINAS, я получу эту ошибку.
Я использовал MySQL workBench
.Проблема в том, что вы не можете использовать один и тот же foreign key name
, они должны быть unique
.Таким образом, если более чем одна таблица будет ссылаться на один и тот же внешний ключ, каждый раз должен быть unique
дано имя.
У меня была аналогичная ошибка в одной из моих таблиц.При установке флажка параметры сортировки столбцов отличались, что сработало после того, как оба столбца были переведены на один и тот же тип сортировки.
После прочтения большей части предлагаемого здесь решения.Я просто подумал, что было бы полезно, если бы я просто перечислил все возможности, которые могли бы вызвать эту ошибку.
1, Проверьте РЕГИСТР столбца 2, Проверьте сопоставление столбцов 3, Проверьте, существует ли ключ, созданный в обеих таблицах для столбца (уникальный, первичный)
В моем случае я получил старое определение таблицы MyISAM в одной из таблиц, и, очевидно, я не смог создать для нее внешний ключ из другой таблицы.Может быть, это кому-то поможет.
Таким образом, это может произойти из-за несоответствий между двумя определениями баз данных / полей, попробуйте проверить:
Field Type
Field Collation
Table Engine
Для меня проблема заключалась в использовании CONSTRAINT
в CREATE TABLE
запрос.
Вы также можете столкнуться с той же ошибкой при попытке сослаться на составной ключ в вашем внешнем ключе.
Например:
CREATE TABLE `article` (
`id` int(10) unsigned NOT NULL,
`type` enum('X','Y','Z') NOT NULL,
PRIMARY KEY (`id`,`type`)
) ENGINE InnoDB;
CREATE TABLE `t1` (
`user_id` int(10) unsigned NOT NULL,
`type` enum('X','Y','Z') NOT NULL,
`article_id` int(10) unsigned NOT NULL,
CONSTRAINT `user_access_article_ibfk_2` FOREIGN KEY (`article_id`, `type`) REFERENCES `article` (`id`, `type`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
В этом случае важно использовать article_id и поле type в определении FK в том же порядке, в каком они отображаются в определении ПЕРВИЧНОГО КЛЮЧА таблицы article.
В моем случае, вероятно, это была ошибка сервера, из-за которой была удалена таблица с тем же именем.Удаление всей shcema и ее повторное создание решило проблему.
В очень странных случаях ваша база данных может быть повреждена.В моем случае у меня не было никаких внешних ключей в таблице, и помогло только переименование таблицы или смена движка.
Оказалось, InnoDB был сломан, видите: https://dba.stackexchange.com/questions/86853/1025-error-on-rename-of-table-errno-150-table-was-deleted-while-tried-to-a?lq=1
Если вы работаете с mysql workbench и получаете эту ошибку для таблицы отношений, возможно, для вас найдется быстрое решение:просто удалите его, и пусть mysql workbench воссоздаст его для вас.Затем скопируйте sql.Исправлена моя проблема с errno 150.
Я получил эту ошибку при попытке использовать внешний ключ для ссылки на неуникальное поле.(который по - видимому не допускается)
Когда у меня возникла эта проблема, это было из-за того, что я установил идентификатор в первой таблице равным unsigned
принимая во внимание, что внешнего ключа во второй таблице не было.Делая их обоих unsigned
починил это для меня.
Всегда сначала создавайте главные / родительские таблицы, а затем создавайте свои подробные / дочерние таблицы.