错误:错误1005:无法创建表(错误编号:121)

110
我在将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)

我不明白为什么。有人可以帮我吗?

3
如果您在服务器上拥有管理员权限,当出现错误时,您可以首先运行MySQL命令“SHOW INNODB STATUS”(或MySQL 5.5“SHOW ENGINE INNODB STATUS”)。该命令会显示日志信息和错误细节。从那里,您可以看到哪里出了问题。 - Dorvalla
1
@Dorvalla的回答解决了这个问题。实际上,当您运行INNODB状态命令时,详细的错误日志存储在“status”列的“LATEST FOREIGN KEY ERROR”部分中。 - Devy
8个回答

247

我为你快速搜索了一下,找到了这里。引用如下:

如果您试图添加一个已在其他地方使用的名称的约束,则会收到此消息。

要检查约束,请使用以下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
尝试使用此线程:http://thenoyes.com/littlenoise/?p=81 尝试删除限制条件,否则你会对其进行更改。我不确定如何更改它,因为我不熟悉它,但是如果您可以调用约束条件,似乎逻辑上您也可以删除它们或更改它们。 - Dorvalla
最常见的错误是尝试两次使用相同的外键名称! - Harm

31

外键约束名称在数据库中必须唯一

@Dorvalla的回答和上面提到的这篇博客文章都指引我找到了解决问题的方向;后者的引用如下:

如果你创建的表包含外键约束,并且你为该约束提供了自己的名称,请记住它必须在整个数据库中是唯一的。

我之前不知道这一点。我已经按照以下模式更改了我的外键约束名称,似乎Ruby on Rails应用程序也在使用这种模式:

<TABLE_NAME>_<FOREIGN_KEY_COLUMN_NAME>_fk

对于OP的表格来说,例如Link_lession_id_fk


7
您可以登录MySQL并输入以下命令:
mysql> SHOW INNODB STATUS\G

你将获得所有输出并更好地了解错误的原因。

1
在MySQL 5.5中,使用的命令是SHOW ENGINE INNODB STATUS。必须在出现错误后立即运行该命令以获取相关信息。 - Devy

3
我遇到了这个错误(errno 121),但是它是由MySQL创建的中间表造成的,这些表已经变成了孤立的,阻止我修改一个表,即使在我的所有表中都不存在这样的约束名。在某个时刻,我的MySQL崩溃或未能清理一个中间表(表名以#sql-开头),导致出现如下错误:尝试运行带有某些约束名的ALTER TABLE时,无法创建表“#sql-”(errno 121)。
根据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(手册有误,因为INNODB_SYS_TABLES在这些版本中不存在)。我能够通过在命令行中搜索我的mysql数据目录找到孤立的临时表(与消息中命名的表不匹配)。
find . -iname '#*'

发现文件名(例如 #sql-9ad_15.frm)后,我能够在MySQL中删除该孤立的表:
USE myschema;
DROP TABLE `#mysql50##sql-9ad_15`;

这样做后,我就能够成功地运行我的ALTER TABLE了。
为了完整起见,根据链接的MySQL文档,“#mysql50#前缀告诉MySQL忽略在MySQL 5.1中引入的文件名安全编码。”

2
如果您在某个表中定义了外键,并且该外键的名称在其他地方被用作另一个外键,那么就会出现此错误。

1
如果您想快速修复问题,请再次进行正向工程,并勾选“生成DROP SCHEMA”选项,然后继续操作。
我假设数据库不包含数据,因此删除它不会产生影响。

0
我注意到我的数据库中有“other_database”和“Other_Database”。这就导致了问题,因为我实际上在其他数据库中有相同的参考,这引起了这个神秘的错误!

-3
mysql> SHOW ENGINE INNODB STATUS;

但在我的情况下,只有这种方式才有帮助:
1. 备份当前数据库
2. 删除数据库(不是所有表格,而是数据库)
3. 创建数据库(检查您仍然拥有权限)
4. 从备份还原数据库

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接