BŁĄD: Błąd 1005: Nie można utworzyć tabeli (errno: 121)

108

Mam kłopoty z forward engineeringmoją bazą danych MySQL na serwerze WAMP .. Zamierzałem zamieścić obraz schematu, ale ponieważ jest to mój pierwszy wpis, nie mogę.

Poniżej znajduje się wykonany skrypt ..

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', '[email protected]', 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', '[email protected]', 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', '[email protected]', 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', '[email protected]', 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', '[email protected]', 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', '[email protected]', 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;

Ale potem pojawia się ten błąd:

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

Nie wiem, dlaczego. Czy ktoś może mi pomóc?

user1703514
źródło
2
Jeśli masz uprawnienia administratora na serwerze, możesz zacząć od uruchomienia polecenia MySQL „SHOW INNODB STATUS” (lub MySQL 5.5 „SHOW ENGINE INNODB STATUS”) natychmiast po otrzymaniu błędu. To polecenie wyświetla informacje dziennika i szczegóły błędu. Stamtąd widać, gdzie idzie źle
Dorvalla
1
Odpowiedź @Dorvalla rozwiązała problem. W rzeczywistości szczegółowy dziennik błędów jest przechowywany w LATEST FOREIGN KEY ERRORsekcji statuskolumny po uruchomieniu polecenia statusu INNODB.
Devy

Odpowiedzi:

237

Szybko cię szukałem i przywiodło mnie tutaj . Cytuję:

Otrzymasz tę wiadomość, jeśli próbujesz dodać ograniczenie o nazwie, która jest już używana w innym miejscu

Aby sprawdzić ograniczenia, użyj następującego zapytania SQL:

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

Poszukaj tam więcej informacji lub spróbuj zobaczyć, gdzie występuje błąd. Wygląda na to, że mam problem z obcym kluczem.

Dorvalla
źródło
Jak dotąd ta odpowiedź była najlepsza… dzięki… więc co wyszło, że były 3 ograniczenia, z których 2 są takie same… ale czy te, które są takie same, pochodzą z tabeli, którą usunąłem wcześniej? Więc co mam zrobić?
user1703514
1
Wypróbuj ten wątek Spróbuj usunąć ograniczenie, inaczej je zmienisz. Nie jestem pewien, jak to zrobić, ponieważ nie jestem z tym zaznajomiony, ale wydaje się logiczne, że możesz wywołać ograniczenia, możesz je również usunąć lub zmienić.
Dorvalla
Najczęściej próbujesz użyć tej samej nazwy klucza obcego dwa razy!
Harm
26

Nazwy ograniczeń klucza obcego muszą być unikalne w bazie danych

Zarówno odpowiedź @ Dorvalla, jak i ten wpis na blogu, o którym mowa powyżej, wskazały mi właściwy kierunek, aby samemu rozwiązać problem; cytując z tego ostatniego:

Jeśli tabela, którą próbujesz utworzyć, zawiera ograniczenie związane z kluczem obcym i podałeś własną nazwę dla tego ograniczenia, pamiętaj, że musi być ona unikalna w bazie danych.

Nie byłem tego świadomy. Zmieniłem nazwy ograniczeń klucza obcego zgodnie z następującym schematem, który wydaje się być używany również przez aplikacje Ruby on Rails:

<TABLE_NAME>_<FOREIGN_KEY_COLUMN_NAME>_fk

W przypadku stołu PO byłby to Link_lession_id_fkna przykład.

Chriki
źródło
6

Możesz zalogować się do mysql i wpisać

mysql> SHOW INNODB STATUS\G

Otrzymasz wszystkie dane wyjściowe i powinieneś mieć lepsze pojęcie o tym, na czym polega błąd.

Marc
źródło
1
W MySQL 5.5 to SHOW ENGINE INNODB STATUS. Aby uzyskać odpowiednie informacje, należy go uruchomić natychmiast po pojawieniu się błędu.
Devy
2

Jeśli masz definicję klucza obcego w jakiejś tabeli, a nazwa klucza obcego jest używana w innym miejscu jako inny klucz obcy, wystąpi ten błąd.

giuseppe
źródło
2

Napotkałem ten błąd (errno 121), ale był on spowodowany przez oddzielone tabele pośrednie utworzone przez mysql, które uniemożliwiły mi zmianę tabeli, mimo że żadna taka nazwa ograniczenia nie istniała w żadnej z moich tabel. W pewnym momencie mój MySQL uległ awarii lub nie udało się wyczyścić tabeli pośredniej (nazwa tabeli zaczynająca się od # sql-), co zakończyło się wyświetleniem mi błędu takiego jak: Can't create table '# sql-' (errno 121) podczas próby uruchomienia ALTER TABLE z określonymi nazwami ograniczeń.

Zgodnie z dokumentacją na http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html możesz wyszukiwać te osierocone tabele za pomocą:

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

Wersja, z którą pracowałem to 5.1, ale powyższe polecenie działa tylko na wersjach> = 5.6 (instrukcja jest niepoprawna co do tego, że działa dla 5.5 lub wcześniejszych, ponieważ INNODB_SYS_TABLES nie istnieje w takich wersjach). Udało mi się znaleźć osieroconą tabelę tymczasową (która nie pasowała do tej wymienionej w wiadomości), przeszukując mój katalog danych mysql w wierszu poleceń:

find . -iname '#*'

Po odkryciu nazwy pliku, takiej jak # sql-9ad_15.frm, mogłem upuścić tę osieroconą tabelę w MySQL:

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

Po wykonaniu tej czynności mogłem pomyślnie uruchomić ALTER TABLE.

Dla kompletności, zgodnie z dołączoną dokumentacją MySQL, „prefiks # mysql50 # mówi MySQL, aby ignorował bezpieczne kodowanie nazw plików wprowadzone w MySQL 5.1”.

Patrick Brown
źródło
1

Jeśli chcesz szybko naprawić, naprzód Inżynier ponownie i zaznacz opcję "Generuj SCHEMAT UPADKU" i kontynuuj.

Zakładam, że baza danych nie zawiera danych, więc jej usunięcie nie będzie miało wpływu.

itsraja
źródło
0

Zauważyłem, że mam w swoich bazach danych „other_database” i „Other_Database”. To spowodowało ten problem, ponieważ faktycznie miałem to samo odniesienie w innej bazie danych, które spowodowało ten tajemniczy błąd!

Roozbeh G
źródło
-3
mysql> SHOW ENGINE INNODB STATUS;

Ale w moim przypadku tylko ten sposób może pomóc:
1. Zrób kopię zapasową aktualnej bazy danych
2. Usuń bazę danych (nie wszystkie tabele, ale DB)
3. Utwórz bazę danych (sprawdź, czy nadal masz poprzednie wersje)
4. Przywróć bazę danych z kopii zapasowej

phpWebStudio
źródło