Mysql复合密钥从外部复合密钥中删除
我试图在Mysql WorkBench中的两个表之间建立多对多关系,其中一个表有一个复合主键(部分来自两个外键)。当我尝试生成SQL时,出现以下错误: 错误:错误1215:无法添加外键约束 SQL代码:Mysql复合密钥从外部复合密钥中删除,mysql,many-to-many,foreign-key-relationship,composite-primary-key,composite-key,Mysql,Many To Many,Foreign Key Relationship,Composite Primary Key,Composite Key,我试图在Mysql WorkBench中的两个表之间建立多对多关系,其中一个表有一个复合主键(部分来自两个外键)。当我尝试生成SQL时,出现以下错误: 错误:错误1215:无法添加外键约束 SQL代码: -- ----------------------------------------------------- -- Table `A_D_schema`.`Resources_has_OwnerGroups` -- --------------------------
-- -----------------------------------------------------
-- Table `A_D_schema`.`Resources_has_OwnerGroups`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `A_D_schema`.`Resources_has_OwnerGroups` (
`Resources_id` INT NOT NULL,
`OwnerGroups_id` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Instances_idInstances` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Customers_idCustomers` INT NOT NULL,
PRIMARY KEY (`Resources_id`, `OwnerGroups_id`, `OwnerGroups_Instances_has_Customers_Instances_idInstances`, `OwnerGroups_Instances_has_Customers_Customers_idCustomers`),
INDEX `fk_Resources_has_OwnerGroups_OwnerGroups1_idx` (`OwnerGroups_id` ASC, `OwnerGroups_Instances_has_Customers_Instances_idInstances` ASC, `OwnerGroups_Instances_has_Customers_Customers_idCustomers` ASC),
INDEX `fk_Resources_has_OwnerGroups_Resources1_idx` (`Resources_id` ASC),
CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1`
FOREIGN KEY (`Resources_id`)
REFERENCES `A_D_schema`.`Resources` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`)
REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
从显示引擎INNODB状态的中,我可以看到以下消息:
Cannot resolve column name close to:
)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`)
REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
显示创建表资源
和显示创建表所有者组
:
CREATE TABLE `Resources` (
`idResources` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(45) DEFAULT NULL,
`role` int(11) DEFAULT NULL COMMENT 'role : 1 disptcher \n0 admin',
PRIMARY KEY (`idResources`),
UNIQUE KEY `idresources_UNIQUE` (`idResources`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `OwnerGroups` (
`idOwnerGroups` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`group` int(11) DEFAULT NULL,
PRIMARY KEY (`idOwnerGroups`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
您的资源表没有列id
。它的主键是idResources
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`)
REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`)
您的OwnerGroups表没有列id
。它的主键是idOwnerGroups
。它根本没有您引用的其他两列
通常,在声明外键时,首先要命名子表中的列:
CREATE TABLE Child (
childCol1 INT,
childCol2 INT,
...
FOREIGN KEY (childCol1, childCol2) ...
然后引用父表中的列:
... REFERENCES Parent (parentCol1, parentCol2)
);
CREATE TABLE Parent (
parentCol1 INT,
parentCol2 INT,
PRIMARY KEY (parentCol1)
);
必须使用父表中的列名称
父表中引用的列必须同时是该表的主键或唯一键。换句话说,鉴于上述示例,它不适用于此父表:
... REFERENCES Parent (parentCol1, parentCol2)
);
CREATE TABLE Parent (
parentCol1 INT,
parentCol2 INT,
PRIMARY KEY (parentCol1)
);
因为主键不包括parentCol2
在您的情况下,以下各项应起作用:
CREATE TABLE IF NOT EXISTS `A_D_schema`.`Resources_has_OwnerGroups` (
`Resources_id` INT NOT NULL,
`OwnerGroups_id` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Instances_idInstances` INT NOT NULL,
`OwnerGroups_Instances_has_Customers_Customers_idCustomers` INT NOT NULL,
PRIMARY KEY (`Resources_id`, `OwnerGroups_id`, `OwnerGroups_Instances_has_Customers_Instances_idInstances`, `OwnerGroups_Instances_has_Customers_Customers_idCustomers`),
CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1`
FOREIGN KEY (`Resources_id`)
REFERENCES `A_D_schema`.`Resources` (`idResources`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1`
FOREIGN KEY (`OwnerGroups_id`)
REFERENCES `A_D_schema`.`OwnerGroups` (`idOwnerGroups`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
) ENGINE = InnoDB
我拿出了两个冗余的索引定义。您不需要索引主键,它已经是表的聚集索引了。您不需要为外键声明中使用的列编制索引,MySQL将在需要时自动为该列编制索引(尽管如果该列已经存在索引,FK约束将使用该索引)
我不确定我是否理解您的另外两列OwnerGroups\u Instances\u has\u Customers\u Instances\u idInstances
和OwnerGroups\u Instances\u has\u Customers\u idCustomers
。通常在多对多表中,您只需要足够的列来引用相应父表的主键
请回复您的评论:
您应该不时尝试刷新架构的视图。在“模式”的右边有一个按钮,上面有一对弯曲的箭头
好的,谢谢你的评论。我注意到它来自世行。我将id命名为idResources,并将其重命名为id。但它仍然存在于脚本中。在左侧面板上,我甚至可以看到具有重复名称的表,这些表是我从…删除的。。。。我删除了资源\u拥有\u所有者组,它仍然存在于脚本中。WB被窃听了吗?所以如果我正确理解了你的评论,那么复合键的最佳实践是什么?假设对于表Resources\u has\u OwnerGroups:创建一个新的键Resources\u has\u OwnerGroups\u id,由fk\u Resources\u id和fk\u OwnerGroups\u id组成?主键(Resources\u id,OwnerGroups\u id)
将是最佳实践。如果包含更多列,则允许前两列存在重复项。主键的成员是列,而不是FK约束。