ПОМИЛКА: Помилка 1005: не вдається створити таблицю (помилка: 121)


108

У мене є проблеми з forward engineeringмоєю базою даних MySQL на сервері WAMP .. Я збирався розмістити зображення схеми, але оскільки це мій перший пост, я не можу.

Нижче виконаний сценарій ..

use aquaticstar;

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,ALLOW_INVALID_DATES';

-- -----------------------------------------------------
-- Table `Students`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `Students` ;

CREATE  TABLE IF NOT EXISTS `Students` (
  `id` VARCHAR(10) NOT NULL ,
  `studentName` VARCHAR(45) NOT NULL ,
  `gender` CHAR NOT NULL ,
  `birthDate` DATETIME NOT NULL ,
  `mNo` VARCHAR(10) NOT NULL ,
  `contactName` VARCHAR(45) NOT NULL ,
  `contactEmail` VARCHAR(45) NOT NULL ,
  `contactPhone` INT(10) NOT NULL ,
  `startDate` DATETIME NOT NULL ,
  `remarks` VARCHAR(200) NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `Waiting List`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `Waiting List` ;

CREATE  TABLE IF NOT EXISTS `Waiting List` (
  `wait_id` VARCHAR(5) NOT NULL ,
  `name` VARCHAR(45) NULL ,
  `contactName` VARCHAR(45) NULL ,
  `contactPhone` INT(10) NULL ,
  `contactEmail` VARCHAR(45) NULL ,
  `status` CHAR NULL ,
  `remarks` VARCHAR(200) NULL ,
  PRIMARY KEY (`wait_id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `Schedule`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `Schedule` ;

CREATE  TABLE IF NOT EXISTS `Schedule` (
  `lesson_id` VARCHAR(10) NOT NULL ,
  `day` VARCHAR(3) NOT NULL ,
  `branch` VARCHAR(30) NOT NULL ,
  `level` VARCHAR(30) NOT NULL ,
  `time` TIME NOT NULL ,
  `ae` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`lesson_id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `Link`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `Link` ;

CREATE  TABLE IF NOT EXISTS `Link` (
  `link_id` VARCHAR(10) NOT NULL ,
  `id` VARCHAR(10) NOT NULL ,
  `lesson_id` VARCHAR(10) NOT NULL ,
  PRIMARY KEY (`link_id`) ,
  INDEX `id_idx` (`id` ASC) ,
  INDEX `lesson_id_idx` (`lesson_id` ASC) ,
  CONSTRAINT `id`
    FOREIGN KEY (`id` )
    REFERENCES `Students` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `lesson_id`
    FOREIGN KEY (`lesson_id` )
    REFERENCES `Schedule` (`lesson_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `Attendance`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `Attendance` ;

CREATE  TABLE IF NOT EXISTS `Attendance` (
  `date` DATETIME NOT NULL ,
  `attendance` VARCHAR(5) NOT NULL ,
  `link_id` VARCHAR(10) NOT NULL ,
  INDEX `link_id_idx` (`link_id` ASC) ,
  CONSTRAINT `link_id`
    FOREIGN KEY (`link_id` )
    REFERENCES `Link` (`link_id` )
    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;

-- -----------------------------------------------------
-- Data for table `Students`
-- -----------------------------------------------------
START TRANSACTION;
INSERT INTO `Students` (`id`, `studentName`, `gender`, `birthDate`, `mNo`, `contactName`, `contactEmail`, `contactPhone`, `startDate`, `remarks`) VALUES ('s001', 'Sam Khew', 'm', '12/12/1991', 'nm', 'May Khew', 'may@gmail.com', 0198829387, '12/07/2011', NULL);
INSERT INTO `Students` (`id`, `studentName`, `gender`, `birthDate`, `mNo`, `contactName`, `contactEmail`, `contactPhone`, `startDate`, `remarks`) VALUES ('s002', 'Joe Biden', 'm', '13/03/2003', 'nm', 'Layla Biden', 'layla@gmail.com', 0199283763, '14/05/2011', NULL);
INSERT INTO `Students` (`id`, `studentName`, `gender`, `birthDate`, `mNo`, `contactName`, `contactEmail`, `contactPhone`, `startDate`, `remarks`) VALUES ('s003', 'Bob Builder', 'm', '14/02/2002', 'LK920K', 'Mama Builder', 'mama@yahoo.com', 0167728376, '29/02/2012', NULL);
INSERT INTO `Students` (`id`, `studentName`, `gender`, `birthDate`, `mNo`, `contactName`, `contactEmail`, `contactPhone`, `startDate`, `remarks`) VALUES ('s004', 'Kenny Koh', 'm', '18/02/1999', 'MM992', 'Lisa Koh', 'lk@hotmail.com', 0123160231, '19/01/2012', NULL);
INSERT INTO `Students` (`id`, `studentName`, `gender`, `birthDate`, `mNo`, `contactName`, `contactEmail`, `contactPhone`, `startDate`, `remarks`) VALUES ('s005', 'Jane Doe', 'f', '29/09/1999', 'nm', 'Jackie Doe', 'jackied@gmail.com', 0127736254, '02/03/2012', NULL);
INSERT INTO `Students` (`id`, `studentName`, `gender`, `birthDate`, `mNo`, `contactName`, `contactEmail`, `contactPhone`, `startDate`, `remarks`) VALUES ('s006', 'Lola Lai', 'f', '02/05/2004', 'nm', 'Mark Lai', 'mark@gmail.com', 0198827365, '11/09/2011', NULL);

COMMIT;

-- -----------------------------------------------------
-- Data for table `Schedule`
-- -----------------------------------------------------
START TRANSACTION;
INSERT INTO `Schedule` (`lesson_id`, `day`, `branch`, `level`, `time`, `ae`) VALUES ('sat1_s4', 'Sat', 'Sunway', 'basic', '4pm', 'Aini');
INSERT INTO `Schedule` (`lesson_id`, `day`, `branch`, `level`, `time`, `ae`) VALUES ('sat1_s5', 'Sat', 'Sunway', 'basic', '5pm', 'Aini');
INSERT INTO `Schedule` (`lesson_id`, `day`, `branch`, `level`, `time`, `ae`) VALUES ('sat1_s6', 'Sat', 'Sunway', 'basic', '6pm', 'Aini');
INSERT INTO `Schedule` (`lesson_id`, `day`, `branch`, `level`, `time`, `ae`) VALUES ('sat2_s4', 'Sat', 'Sunway', 'advance', '4pm', 'Nina');
INSERT INTO `Schedule` (`lesson_id`, `day`, `branch`, `level`, `time`, `ae`) VALUES ('sat2_s5', 'Sat', 'Sunway', 'advance', '5pm', 'Nina');
INSERT INTO `Schedule` (`lesson_id`, `day`, `branch`, `level`, `time`, `ae`) VALUES ('sat3_s6', 'Sat', 'Sunway', 'pre-comp', '6pm', 'Marcus');

COMMIT;

-- -----------------------------------------------------
-- Data for table `Link`
-- -----------------------------------------------------
START TRANSACTION;
INSERT INTO `Link` (`link_id`, `id`, `lesson_id`) VALUES ('L001', 's001', 'sat1_s4');
INSERT INTO `Link` (`link_id`, `id`, `lesson_id`) VALUES ('L002', 's002', 'sat1_s5');
INSERT INTO `Link` (`link_id`, `id`, `lesson_id`) VALUES ('L003', 's003', 'sat1_s6');
INSERT INTO `Link` (`link_id`, `id`, `lesson_id`) VALUES ('L004', 's004', 'sat2_s4');
INSERT INTO `Link` (`link_id`, `id`, `lesson_id`) VALUES ('L005', 's005', 'sat1_s5');

COMMIT;

-- -----------------------------------------------------
-- Data for table `Attendance`
-- -----------------------------------------------------
START TRANSACTION;
INSERT INTO `Attendance` (`date`, `attendance`, `link_id`) VALUES ('26/9/2012', '1', NULL);

COMMIT;

Але тоді я отримую цю помилку:

Executing SQL script in server
ERROR: Error 1005: Can't create table 'aquaticstar.link' (errno: 121)

Я не можу зрозуміти, чому. Хтось може мені допомогти?


2
Якщо у вас є дозвіл адміністратора на сервері, ви можете почати, запустивши команду MySQL «SHOW INNODB STATUS» (або MySQL 5.5 «SHOW ENGINE INNODB STATUS») відразу після отримання помилки. Ця команда відображає інформацію про журнал та дані про помилки. Звідти ви можете побачити, куди йде не так
Дорвалла

1
Відповідь @Dorvalla вирішила це. Фактично, журнал помилок з деталізацією зберігається у LATEST FOREIGN KEY ERRORрозділі statusстовпця під час запуску команди статусу INNODB.
Devy

Відповіді:


237

Я швидко шукав вас, і це мене привело сюди . Цитую:

Це повідомлення ви отримаєте, якщо намагаєтесь додати обмеження з іменем, яке вже використовується десь в іншому місці

Для перевірки обмежень використовуйте наступний SQL-запит:

SELECT
    constraint_name,
    table_name
FROM
    information_schema.table_constraints
WHERE
    constraint_type = 'FOREIGN KEY'
AND table_schema = DATABASE()
ORDER BY
    constraint_name;

Знайдіть додаткову інформацію там або спробуйте побачити, де виникає помилка. Схоже, проблема із зовнішнім ключем для мене.


Ця відповідь була найкращою до цих пір .. дякую .. так що придумали, що було 3 обмеження, 2 з яких однакові ... але так, ті ж самі прийшли з таблиці, яку я видалив раніше? То що мені робити?
user1703514

1
Спробуйте цю тему Спробуйте видалити обмеження, інакше ви зміните його. Я не впевнений, як, бо я не знайомий з цим, але, здавалося б, логічно, якщо ви можете викликати обмеження, ви також можете їх видалити або змінити.
Дорвалла

Найчастіше ви намагаєтесь використовувати одне і те ж ім'я іноземного ключа двічі!
Шкода

26

Імена іноземних ключових обмежень повинні бути унікальними в базі даних

Відповідь @ Дорвалли та згадана вище публікація в блозі вказали мене на правильний напрямок, щоб вирішити проблему для себе; цитуючи з останнього:

Якщо таблиця, яку ви намагаєтеся створити, містить обмеження іноземного ключа, і ви вказали власне ім’я для цього обмеження, пам’ятайте, що воно повинно бути унікальним у базі даних.

Я цього не знав. Я змінив свої імена обмежень за зовнішніми ключами відповідно до наступної схеми, яка, як видається, використовується також додатками Ruby on Rails:

<TABLE_NAME>_<FOREIGN_KEY_COLUMN_NAME>_fk

Наприклад, для таблиці ОП це було б Link_lession_id_fk.


6

Ви можете увійти в mysql та набрати

mysql> SHOW INNODB STATUS\G

У вас буде весь результат, і ви маєте краще уявити, що таке помилка.


1
У MySQL 5.5 це SHOW ENGINE INNODB STATUS. І його потрібно запустити відразу після отримання помилки, щоб отримати відповідну інформацію.
Devy

2

Якщо у вас є визначення іноземного ключа в якійсь таблиці, а ім'я зовнішнього ключа використовується в іншому місці як інший зовнішній ключ, ви отримаєте цю помилку.


2

Я зіткнувся з цією помилкою (errno 121), але вона була викликана створеними mysql проміжними таблицями, осиротілими, що заважало мені змінювати таблицю, хоча в жодній із моїх таблиць такого імені обмеження не існувало. У якийсь момент мій MySQL вийшов з ладу або не зміг очистити проміжну таблицю (назва таблиці, починаючи з # sql-), що в результаті представило мені помилку, наприклад: Не вдається створити таблицю '# sql-' (помилка 121) при спробі запустити ALTER TABLE з певними іменами обмежень.

Згідно з документами на веб- сайті http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html , ви можете шукати ці осиротілі таблиці за допомогою:

SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql%';

Версія, з якою я працював, була 5.1, але наведена вище команда працює лише у версіях> = 5.6 (вручну невірно, якщо вона працює для версії 5.5 або раніше, оскільки INNODB_SYS_TABLES не існує в таких версіях). Я зміг знайти осиротілу тимчасову таблицю (яка не відповідає тій, яку названо в повідомленні), виконавши пошук у моєму каталозі даних mysql у командному рядку:

find . -iname '#*'

Після виявлення імені файлу, такого як # sql-9ad_15.frm, я зміг скинути цю осиротілу таблицю в MySQL:

USE myschema;
DROP TABLE `#mysql50##sql-9ad_15`;

Після цього мені вдалося успішно запустити свою НАЗАДУ ТАБЛИЦЮ.

Для повноти, відповідно до документації, пов’язаної з MySQL, "префікс # mysql50 # вказує MySQL ігнорувати безпечне кодування імені файлів, введене в MySQL 5.1."


1

Якщо ви хочете швидко виправити, виправити інженера ще раз і встановіть прапорець "Створити схему DROP SCHEMA" та продовжуйте.

Я припускаю, що база даних не містить даних, тому відмова від неї не вплине.


0

Щось я помітив, це те, що у мене в базах даних були "other_database" та "Other_Database". Це спричинило цю проблему, оскільки я фактично мав таке ж посилання в іншій базі даних, що спричинило цю таємничу помилку!


-3
mysql> SHOW ENGINE INNODB STATUS;

Але в моєму випадку тільки такий спосіб міг допомогти:
1. Зробіть резервну копію поточної БД
2. Відкиньте БД (не всі таблиці, але БД)
3. Створіть БД (перевірте, чи є у вас ще переваги)
4. Відновіть БД із резервної копії.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.