错误编号121,写入或更新时出现重复键?

38
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';

CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE `mydb` ;

-- -----------------------------------------------------
-- Table `mydb`.`restaurants`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`restaurants` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(128) NOT NULL ,
  `description` VARCHAR(1024) NOT NULL ,
  `address` VARCHAR(1024) NOT NULL ,
  `phone` VARCHAR(16) NOT NULL ,
  `url` VARCHAR(128) NOT NULL ,
  `min_order` INT NOT NULL ,
  `food_types` SET('pizza', 'sushi', 'osetian_pie') NOT NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `name_UNIQUE` (`name` ASC) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`regions`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`regions` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `restaurant` INT NOT NULL ,
  `name` VARCHAR(128) NOT NULL ,
  PRIMARY KEY (`id`) ,
  INDEX `restaurant_idx` (`restaurant` ASC) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) ,
  CONSTRAINT `restaurant`
    FOREIGN KEY (`restaurant` )
    REFERENCES `mydb`.`restaurants` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`food`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`food` (
  `id` INT NOT NULL ,
  `type` ENUM('pizza', 'sushi', 'osetian_pie') NOT NULL ,
  `name` VARCHAR(45) NOT NULL ,
  `ingredients` VARCHAR(256) NULL ,
  `image` VARCHAR(256) NOT NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`food_variant`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`food_variant` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `size` VARCHAR(16) NOT NULL ,
  `weight` VARCHAR(16) NOT NULL ,
  `price` INT NOT NULL ,
  `food` INT NOT NULL ,
  `restaurant` INT NOT NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) ,
  INDEX `food_idx` (`food` ASC) ,
  INDEX `restaurant_idx` (`restaurant` ASC) ,
  CONSTRAINT `food`
    FOREIGN KEY (`food` )
    REFERENCES `mydb`.`food` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `restaurant`
    FOREIGN KEY (`restaurant` )
    REFERENCES `mydb`.`restaurants` (`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;

Error is:
    Executing SQL script in server
    ERROR: Error 1005: Can't create table 'mydb.food_variant' (errno: 121)

我看不到重复的约束条件。它在哪里?


6个回答

45

这可能是因为您将至少一个约束命名为与列相同的标识符:

/* You already have a column named `restaurant` in this table, 
   but are naming the FK CONSTRAINT `restaurant` also... */
CONSTRAINT `restaurant`
    FOREIGN KEY (`restaurant` )
    REFERENCES `mydb`.`restaurants` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

应该使用一个不同的约束标识符,例如 fk_restaurant

CONSTRAINT `fk_restaurant`
    FOREIGN KEY (`restaurant` )
    REFERENCES `mydb`.`restaurants` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

food表中同样的事情:

  /* Name it fk_food */
  CONSTRAINT `fk_food`
    FOREIGN KEY (`food` )
    REFERENCES `mydb`.`food` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  /* Name it fk_restaurant */
  CONSTRAINT `fk_restaurant`
    FOREIGN KEY (`restaurant` )
    REFERENCES `mydb`.`restaurants` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

我只看到了这三个,但可能会有其他我没注意到的。


16
如果有人遇到此问题,我曾在多个表中更改约束名后仍然收到错误编号121。问题是,即使在不同的表中,您也不能使用相同的约束名。我在table1和table2中都使用了“fk_entryid”,因此必须将它们分别更改为“fk_table1_entryid”和“fk_table2_entryid”才能使其正常工作。这发生在MySQLWorkbench和MariaDB中,如果这很重要的话。 - Jose Cifuentes

16

这个答案来自于@Michael Berkowski的答案评论。我将其发布为答案,因为它对我非常有效:

即使在多个表中更改了约束名,我仍然遇到了errno 121的问题。问题在于,即使在不同的表中,您也不能使用相同的约束名。我在table1和table2中都使用了fk_entryid,必须将它们分别更改为fk_table1_entryidfk_table2_entryid才能使其正常工作。


8
以上所有回答都非常好,但即使我删除了所有表格,仍然没有解决我的问题。但在我删除数据库并重新创建后,一切都运行得非常完美,迁移也很顺利……似乎密钥被缓存并且在表格被删除后没有被清除。
注意:这不是对问题的回答,而是我个人的经验,我觉得可能会帮助其他人。

这也是我的问题。我不得不完全删除数据库。我猜测在一段时间前,当我停止mysql守护进程时遇到问题并不得不强制杀死它时,出了些问题。 - bmakan
和我一样。只需删除数据库并重新导入即可解决问题。 - Yousef Altaf
我们遇到了同样的问题。我们通过停止并重新启动MySQL/MariaDB服务器来解决它。因此,删除数据库可能是不必要的。 - twigmac

0

我正在使用DBeaver22.3.1,并遇到了与下面相同的问题: 也就是说,[外键]节点上没有显示任何项目(见下图)

enter image description here

然而,使用以下的选择语句,它的存在是显而易见的(见第二张图片)。因此,如果我尝试创建一个同名的外键,错误会提示“重复”。

select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
where CONSTRAINT_SCHEMA = 'webstore' 
        AND CONSTRAINT_TYPE = 'FOREIGN KEY';

enter image description here


0

这是对 @peter-moses 的回应,因为我遇到了和他一模一样的问题。

我通过在我的转储命令中添加 --add-drop-database 来解决了这个问题。它在这里有文档记录:https://mariadb.com/kb/en/mysqldump/

我的最终命令看起来像这样:

mysqldump -uroot -ppassword --single-transaction --all-databases --add-drop-database


0

在我的情况下,这是一个非常奇怪的缓存问题。我无法创建新的外键约束,尽管键的名称是唯一的。重新启动MariaDB服务器并不是解决方案,但检查Foreign KeysReferences列表。

例如,在我的数据库导航器中(我正在使用DBeaver),所有我的Foreign Keys列表都是空的。然而,当我导航到引用表并检查其References列表时,我能够看到条目。顺便说一句,当执行针对information_schema的查询时,这些条目也不可见。 ‍♂️

从此列表中删除引用后,我就能够创建新的外键了。

编辑

执行SHOW ENGINE INNODB STATUS;并检查其LATEST FOREIGN KEY ERROR部分可能也有所帮助,因为它提供了有关问题的其他信息/上下文。


我正在使用DBeaver 22.3.1版本,但“Foreign Keys”节点没有显示任何现有的外键,我认为这是一个系统错误。实际上,外键是存在的,我能够在DOS中验证它(而不是在DBeaver脚本中)-- select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_SCHEMA = 'mydb' AND CONSTRAINT_TYPE = 'FOREIGN KEY'; - Park JongBum

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