ERRO: Erro 1005: Não é possível criar a tabela (número do erro: 121)

108

Eu tenho problemas com forward engineeringmeu banco de dados MySQL no servidor WAMP .. Eu ia postar uma imagem do esquema, mas como este é meu primeiro post, não posso.

Abaixo está o script executado.

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;

Mas então recebo este erro:

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

Não consigo descobrir por quê. Alguém pode me ajudar?

user1703514
fonte
2
Se você tem permissão de administrador no servidor, você pode querer começar executando o comando MySQL “SHOW INNODB STATUS” (ou MySQL 5.5 “SHOW ENGINE INNODB STATUS”) imediatamente após receber o erro. Este comando exibe informações de log e detalhes do erro. De lá, você pode ver onde as coisas
deram
1
A resposta de @Dorvalla resolveu. Na verdade, o log de erros detalhado é armazenado na LATEST FOREIGN KEY ERRORseção da statuscoluna quando você executa o comando de status INNODB.
Devy

Respostas:

237

Procurei você rapidamente e isso me trouxe aqui . Eu cito:

Você receberá esta mensagem se estiver tentando adicionar uma restrição com um nome que já seja usado em outro lugar

Para verificar as restrições, use a seguinte consulta SQL:

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

Procure mais informações aqui ou tente ver onde ocorre o erro. Parece um problema com uma chave estrangeira para mim.

Dorvalla
fonte
Esta resposta foi a melhor até agora .. obrigado .. então o que surgiu foi que havia 3 restrições, 2 das quais são iguais ... mas eh as que são as mesmas vieram de uma tabela que excluí antes? Então o que eu faço?
user1703514
1
Experimente este tópico Tente deletar a restrição, senão você a altera. Não sei como, porque não estou familiarizado com isso, mas pareceria lógico se você pudesse chamar as restrições, você pode excluí-las também ou alterá-las.
Dorvalla,
O mais comum é tentar usar o mesmo nome de chave estrangeira duas vezes!
Danos em
26

Os nomes de restrição de chave estrangeira devem ser exclusivos dentro de um banco de dados

Ambos @ resposta de Dorvalla e este post mencionado acima apontou-me na direção certa para resolver o problema por mim mesmo; citando o último:

Se a tabela que você está tentando criar inclui uma restrição de chave estrangeira e você forneceu seu próprio nome para essa restrição, lembre-se de que ela deve ser exclusiva no banco de dados.

Eu não estava ciente disso. Eu mudei meus nomes de restrição de chave estrangeira de acordo com o seguinte esquema, que parece ser usado por aplicativos Ruby on Rails também:

<TABLE_NAME>_<FOREIGN_KEY_COLUMN_NAME>_fk

Para a tabela do OP seria Link_lession_id_fk, por exemplo.

Chriki
fonte
6

Você pode fazer o login no mysql e digitar

mysql> SHOW INNODB STATUS\G

Você terá toda a saída e deverá ter uma ideia melhor de qual é o erro.

Marc
fonte
1
No MySQL 5.5, é SHOW ENGINE INNODB STATUS. E deve ser executado imediatamente após a obtenção do erro para obter as informações relevantes.
Devy
2

Se você tiver uma definição de chave estrangeira em alguma tabela e o nome da chave estrangeira for usado em outro lugar como outra chave estrangeira, você terá este erro.

giuseppe
fonte
2

Enfrentei esse erro (errno 121), mas foi causado por tabelas intermediárias criadas pelo mysql que haviam se tornado órfãs, impedindo-me de alterar uma tabela, embora nenhum nome de restrição existisse em nenhuma de minhas tabelas. Em algum ponto, meu MySQL travou ou não conseguiu limpar uma tabela intermediária (nome da tabela começando com # sql-), o que acabou me apresentando um erro como: Não é possível criar a tabela '# sql-' (errno 121) ao tentar executar um ALTER TABLE com certos nomes de restrição.

De acordo com os documentos em http://dev.mysql.com/doc/refman/5.7/en/innodb-trouwagen-datadict.html , você pode pesquisar essas tabelas órfãs com:

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

A versão com a qual eu estava trabalhando era 5.1, mas o comando acima só funciona nas versões> = 5.6 (o manual está incorreto sobre ele funcionar para 5.5 ou anteriores, porque INNODB_SYS_TABLES não existe nessas versões). Consegui encontrar a tabela temporária órfã (que não correspondia àquela nomeada na mensagem) pesquisando meu diretório de dados mysql na linha de comando:

find . -iname '#*'

Depois de descobrir o nome do arquivo, como # sql-9ad_15.frm, consegui descartar essa tabela órfã no MySQL:

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

Depois de fazer isso, fui capaz de executar com êxito meu ALTER TABLE.

Para completar, de acordo com a documentação do MySQL vinculada, "o prefixo # mysql50 # diz ao MySQL para ignorar a codificação segura de nome de arquivo introduzida no MySQL 5.1."

Patrick Brown
fonte
1

Se você quiser consertar rapidamente, Forward Engineer novamente e marque a opção "Generate DROP SCHEMA" e prossiga.

Presumo que o banco de dados não contenha dados, então descartá-lo não afetará.

itsraja
fonte
0

Algo que notei foi que tinha "other_database" e "Other_Database" em meus bancos de dados. Isso causou esse problema, pois na verdade eu tinha a mesma referência em outro banco de dados que causou esse erro misterioso!

Roozbeh G
fonte
-3
mysql> SHOW ENGINE INNODB STATUS;

Mas no meu caso, apenas desta forma poderia ajudar:
1. Faça backup do banco de dados atual
2. Elimine o banco de dados (não todas as tabelas, mas o banco de dados)
3. Crie o banco de dados (verifique se você ainda tem privilégios)
4. Restaure o banco de dados do backup

phpWebStudio
fonte