ERROR: Error 1005: No se puede crear la tabla (errno: 121)

108

Tengo problemas con forward engineeringmi base de datos MySQL en el servidor WAMP. Iba a publicar una imagen del esquema, pero como esta es mi primera publicación, no puedo.

A continuación se muestra el script ejecutado.

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;

Pero luego me sale este error:

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

No puedo entender por qué. ¿Alguien puede ayudarme?

usuario1703514
fuente
2
Si tiene permiso de administrador en el servidor, puede comenzar ejecutando el comando de MySQL "SHOW INNODB STATUS" (o MySQL 5.5 "SHOW ENGINE INNODB STATUS") inmediatamente después de recibir el error. Este comando muestra información de registro y detalles de error. Desde allí se puede ver dónde sale mal
Dorvalla
1
La respuesta de @Dorvalla lo solucionó. De hecho, el registro de errores detallado se almacena en la LATEST FOREIGN KEY ERRORsección de la statuscolumna cuando ejecuta el comando de estado INNODB.
Devy

Respuestas:

237

Te busqué rápido y me trajo aquí . Yo cito:

Recibirá este mensaje si está intentando agregar una restricción con un nombre que ya se usa en otro lugar

Para comprobar las restricciones, utilice la siguiente 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;

Busque más información allí o intente ver dónde ocurre el error. Me parece un problema con una clave externa.

Dorvalla
fuente
Esta respuesta fue la mejor hasta ahora ... gracias ... así que lo que surgió fue que había 3 restricciones, 2 de las cuales son iguales ... pero ¿eh las que son iguales provienen de una tabla que eliminé antes? ¿Entonces qué hago?
user1703514
1
Pruebe este hilo Intente eliminar la restricción, de lo contrario, modifíquela. No estoy seguro de cómo, porque no estoy familiarizado con él, pero parecería lógico si puede invocar las restricciones, también puede eliminarlas o modificarlas.
Dorvalla
¡Lo más común es que intente usar el mismo nombre de clave externa dos veces!
Daño
26

Los nombres de restricción de clave externa deben ser únicos dentro de una base de datos

Tanto la respuesta de @ Dorvalla como esta publicación de blog mencionada anteriormente me indicaron la dirección correcta para solucionar el problema por mí mismo; citando de este último:

Si la tabla que está intentando crear incluye una restricción de clave externa y ha proporcionado su propio nombre para esa restricción, recuerde que debe ser única dentro de la base de datos.

Yo no estaba consciente de eso. He cambiado los nombres de mis restricciones de clave externa de acuerdo con el siguiente esquema que parece ser utilizado también por las aplicaciones de Ruby on Rails:

<TABLE_NAME>_<FOREIGN_KEY_COLUMN_NAME>_fk

Para la mesa del OP esto sería Link_lession_id_fk, por ejemplo.

Chriki
fuente
6

Puede iniciar sesión en mysql y escribir

mysql> SHOW INNODB STATUS\G

Tendrá todo el resultado y debería tener una mejor idea de cuál es el error.

Bagazo
fuente
1
En MySQL 5.5, es SHOW ENGINE INNODB STATUS. Y debe ejecutarse inmediatamente después de recibir el error para obtener la información relevante.
Devy
2

Si tiene una definición de clave externa en alguna tabla y el nombre de la clave externa se usa en otro lugar como otra clave externa, tendrá este error.

Giuseppe
fuente
2

Me enfrenté a este error (errno 121) pero fue causado por tablas intermedias creadas por mysql que habían quedado huérfanas, lo que me impedía alterar una tabla aunque no existía tal nombre de restricción en ninguna de mis tablas. En algún momento, mi MySQL se bloqueó o no pudo limpiar una tabla intermedia (el nombre de la tabla comienza con un # sql-) que terminó presentándome un error como: No se puede crear la tabla '# sql-' (errno 121) al intentar ejecutar ALTER TABLE con ciertos nombres de restricciones.

De acuerdo con los documentos de http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html , puede buscar estas tablas huérfanas con:

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

La versión con la que estaba trabajando era 5.1, pero el comando anterior solo funciona en versiones> = 5.6 (el manual es incorrecto acerca de que funciona para 5.5 o anterior, porque INNODB_SYS_TABLES no existe en tales versiones). Pude encontrar la tabla temporal huérfana (que no coincidía con la que se menciona en el mensaje) buscando en mi directorio de datos mysql en la línea de comando:

find . -iname '#*'

Después de descubrir el nombre del archivo, como # sql-9ad_15.frm, pude eliminar esa tabla huérfana en MySQL:

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

Después de hacerlo, pude ejecutar con éxito mi ALTER TABLE.

Para completar, según la documentación de MySQL vinculada, "el prefijo # mysql50 # le dice a MySQL que ignore la codificación segura de nombres de archivo introducida en MySQL 5.1".

Patrick Brown
fuente
1

Si desea arreglar rápidamente, Adelante Engineer nuevamente y marque la opción "Generar DROP SCHEMA" y continúe.

Supongo que la base de datos no contiene datos, por lo que eliminarlos no afectará.

itsraja
fuente
0

Algo que noté fue que tenía "other_database" y "Other_Database" en mis bases de datos. Eso causó este problema, ya que en realidad tenía la misma referencia en otra base de datos que causó este misterioso error.

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

Pero en mi caso, solo de esta manera podría ayudar:
1. Hacer una copia de seguridad de la base de datos actual
2. Eliminar la base de datos (no todas las tablas, sino la base de datos)
3. Crear la base de datos (comprobar que todavía tiene privilegios)
4. Restaurar la base de datos desde la copia de seguridad

phpWebStudio
fuente