我发现了一些关于错误的线索。但是所有的解决方案对我都不起作用。
我创建了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;
但这并没有显示任何错误。
答案 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();
现在它起作用了!