使用外键 - 无法插入

时间:2010-03-28 11:56:06

标签: mysql database database-design foreign-keys

在mySQL数据库中使用外键进行我的第一次试用并尝试插入,因此失败:Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails

这是否意味着外键限制INSERTS以及使用外键关系强制执行的每个表上的DELETES和/或UPDATES?

谢谢!

更新说明:

Products
----------------------------
id    | type
----------------------------
0     | 0
1     | 3

ProductsToCategories
----------------------------
productid | categoryid
----------------------------
0         | 0
1         | 1

产品表具有以下结构

CREATE  TABLE IF NOT EXISTS `alpha`.`products` (
  `id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `type` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 ,    
  PRIMARY KEY (`id`) ,  
  CONSTRAINT `funkyfunky`  
    FOREIGN KEY (`id` )
    REFERENCES `alpha`.`ProductsToCategories` (`productid` )    
    ON DELETE CASCADE,    
    ON UPDATE CASCADE)  

ENGINE = InnoDB;

4 个答案:

答案 0 :(得分:4)

您的插入失败,因为您插入的行中的外键与约束表中的有效键不匹配。例如:

假设你有这两个表:

Employees
----------------------------
EmpID | Name
----------------------------
0     | John
1     | Jane

OfficeAssignments
----------------------------
OfficeID | EmpID
----------------------------
0        | 0
1        | 1

如果您在OfficeAssignments.EmpID -> Employees.EmpID上有外键约束,并且您尝试执行:

INSERT INTO OfficeAssignments (OfficeID, EmpID) VALUES (2,2)

该语句将失败,因为Employees表中没有EmpID为2的条目。

约束旨在确保您的从属表始终具有与父表相关的有效数据 - 在此示例中,您将永远不会有一个列为分配给系统中不存在的员工的办公室,或者因为它们从未存在(如本例所示)或者因为它们已被删除(因为约束将阻止员工记录被删除,直到首先删除了办公室分配记录)。

编辑现在您已经发布了约束,它确实看起来可能会向后设置。通过将约束放在Products表的定义中,您将其设为子项,并将ProductsToCategories设置为父项。您编写的约束可以理解为“必须先将产品分配到类别才能创建”。我怀疑你的意思是反过来说:“必须先创建一个产品才能将其分配到一个类别。”要获得该结果,您需要将约束放在ProductsToCategories表上,将外键设置为productid并引用Products.id

答案 1 :(得分:2)

当父表中存在对其进行外键引用时,您无法从父表中删除该行。此外,您无法在外键列中使用无效ID的子表中插入/更新。

编辑:“CONSTRAINT funkyfunky FOREIGN KEY(id)”必须在“ProductsToCategories”表中声明,而不是在“Products”表中声明,因为“ProductsToCategories”引用的“产品”并不像您所做的那样相反。< / p>

答案 2 :(得分:1)

外键强制执行两个表中的行之间的有效关系。为了能够在包含外键的表中插入行,在引用的表中必须有一行包含该键,否则插入将失败。与删除相同,您不能删除引用表中的行,而表中仍有行仍然引用它的外键。防止以依赖表中的行结束具有数据,但在引用的表中没有关联的行,即违反参照完整性。

答案 3 :(得分:1)

您的产品表略有错误,因为您不需要从中引用任何内容。引用进入“其他”表,并指向main,例如:

create table products (
  id int auto_increment,
  type int,
  primary key (id)
);

create table categories (
  id int auto_increment,
  name varchar(128),
  primary key (id)
)

create table products_to_categories (
  product_id int references products,
  category_id int references categories
);