错误代码:1822。无法添加外键constaint。缺少约束索引

时间:2014-10-12 20:43:30

标签: mysql sql

我发现了一些关于错误的线索。但是所有的解决方案对我都不起作用。

我创建了2个用户表和一个用于表的表。现在我想存储创建文章的用户和最后一个修饰符的用户。

CREATE TABLE IF NOT EXISTS `testDb`.`users` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `nickname` VARCHAR(255) NULL,
  `first_name` VARCHAR(255) NULL,
  `last_name` VARCHAR(255) NULL,
  `e_mail` VARCHAR(255) NOT NULL,
  `activated` TINYINT(1) NOT NULL DEFAULT 0,
  `birth_date` DATE NULL,
  `locked` TINYINT(1) NOT NULL DEFAULT 0,
  `locked_date_time` DATETIME NULL,
  `street` VARCHAR(255) NULL,
  `street_number` VARCHAR(255) NULL,
  `city` VARCHAR(255) NULL,
  `postal_code` VARCHAR(255) NULL,
  `country` VARCHAR(255) NULL,
  `phone` VARCHAR(255) NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `user_id_UNIQUE` (`id` ASC)
)
ENGINE = InnoDB
AUTO_INCREMENT = 1;


CREATE TABLE IF NOT EXISTS `testDb`.`articles` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NULL,
  `description` VARCHAR(255) NULL,
  `create_user` INT ZEROFILL NOT NULL,
  `create_date_time` DATETIME NULL,
  `last_modifie_user` INT ZEROFILL NOT NULL,
  `last_modifie_date_time` DATETIME NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `article_id_UNIQUE` (`id` ASC),
  INDEX `fk_articles_users1_idx` (`create_user` ASC),
  INDEX `fk_articles_users2_idx` (`last_modifie_user` ASC)
)
ENGINE = InnoDB
AUTO_INCREMENT = 1;


ALTER TABLE `testDb`.`articles`
  ADD CONSTRAINT `fk_articles_users1`
    FOREIGN KEY (`create_user`)
    REFERENCES `testDb`.`users` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  ADD CONSTRAINT `fk_articles_users2`
    FOREIGN KEY (`last_modifie_user`)
    REFERENCES `testDb`.`users` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION;

我收到以下错误,但我不明白为什么我应该有一个索引。

错误代码:1822。无法添加外键constaint。缺少引用表'users'中的约束'fk_articles_users1'的索引

我主动

SHOW ENGINE innodb STATUS;

但这并没有显示任何错误。

8 个答案:

答案 0 :(得分:12)

create_user INT UNSIGNED ZEROFILL无法引用id INT,因为出于外键引用的目的,它们被视为不同的数据类型。使它们具有相同的数据类型。

外键关系中列之间允许的唯一数据类型差异是varchar的长度。例如,VARCHAR(10)可以引用VARCHAR(20),反之亦然。

数据类型,大小或字符集的任何其他差异与参照完整性不兼容。

即使在一列上有ZEROFILL但在另一列上没有,也会使数据类型不兼容。

答案 1 :(得分:2)

我遇到了这个问题,我的数据类型是正确的,所以我被困了一点但是我只是做了一切。

创建外键时,请确保您使用的列具有相同的内容:

  • 数据类型
  • 整理
  • 零填充
  • 不是
  • 无符号
  • 二进制

答案 2 :(得分:1)

alter table声明中必定存在一些微妙的问题。更改articles的定义可解决问题:

CREATE TABLE IF NOT EXISTS `articles` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NULL,
  `description` VARCHAR(255) NULL,
  `create_user` INT ZEROFILL NOT NULL REFERENCES users(id),
  `create_date_time` DATETIME NULL,
  `last_modifie_user` INT ZEROFILL NOT NULL REFERENCES users(id),
  `last_modifie_date_time` DATETIME NULL,
  PRIMARY KEY (`id`),
  INDEX `fk_articles_users1_idx` (`create_user` ASC),
  INDEX `fk_articles_users2_idx` (`last_modifie_user` ASC)
)
ENGINE = InnoDB
AUTO_INCREMENT = 1;

Here是SQL小提琴。

答案 3 :(得分:0)

您可以使用SHOW FULL COLUMNS FROM table_name返回列排序规则,例如对于accounts列上具有特殊排序规则的表name

mysql> SHOW FULL COLUMNS FROM accounts;
+----------+--------------+-------------------+------+-----+---------+----------+
| Field    | Type         | Collation         | Null | Key | Default | Extra    |
+----------+--------------+-------------------+------+-----+---------+----------|
| id       | int(11)      | NULL              | NO   | PRI | NULL    | auto_inc |
| name     | varchar(255) | utf8_bin          | YES  |     | NULL    |          |
| email    | varchar(255) | latin1_swedish_ci | YES  |     | NULL    |          |
...

两列必须具有相同的排序规则。

change the collation of column

ALTER TABLE t1 MODIFY
    col1 VARCHAR(5)
      CHARACTER SET latin1
      COLLATE latin1_swedish_ci;

发生在我身上。

答案 4 :(得分:0)

在我的情况下,错误是我不知道FK的名称在整个数据库中必须是唯一的。重命名FK可以解决此问题。

答案 5 :(得分:0)

对我来说,问题是我的数据库中的默认排序规则不同。确保您的数据库的默认排序规则与您的 FK 尝试引用的字段的排序规则相匹配。

答案 6 :(得分:0)

确保父表不是另一个表的子表。

答案 7 :(得分:0)

出于某种原因,->unsignedBigInteger() 对我不起作用。

所以我稍微改了一下: $table->unsignedBigInteger('owner_id');

对此: $table->bigInteger('owner_id')->unsigned();

现在它起作用了!