如果您的级联删除一个产品,因为它是一个类别的成员被杀死,那么你设置你的外键不当。给定示例表,您应该设置了以下表:CREATETABLEcategories(
idintunsignednotnullprimarykey,
nameVARCHAR(255)defaultnull)Engine=InnoDB;CREATETABLEproducts(
idintunsignednotnullprimarykey,
nameVARCHAR(255)defaultnull)Engine=InnoDB;CREATETABLEcategories_products(
category_idintunsignednotnull,
product_idintunsignednotnull,
PRIMARYKEY(category_id,product_id),
KEYpkey(product_id),
FOREIGNKEY(category_id)REFERENCEScategories(id)
ONDELETECASCADE
ONUPDATECASCADE,
FOREIGNKEY(product_id)REFERENCESproducts(id)
ONDELETECASCADE
ONUPDATECASCADE)Engine=InnoDB;
通过这种方式,您可以删除产品或类别,并且只有类别_Products中的相关记录才会同时消亡。级联将不会沿着树的更远的方向移动,也不会删除父产品/类别表。
G.products:boots,mittens,hats,coats
categories:red,green,blue,white,black
prod/cats:redboots,greenmittens,redcoats,blackhats
如果删除“红色”类别,那么只有“类别”表中的“红色”条目死亡,以及两个条目“红色靴子”和“红色外套”。
删除将不再级联,也不会删除‘靴子’和‘外套’类别。
评论后续行动:
你还是误解了级联删除的工作原理。它们只影响定义“ON DELETE级联”的表。在本例中,级联是在“类别_产品”表中设置的。如果删除“红色”类别,那么在类别_Products中唯一会级联删除的记录是category_id = red..它不会触及‘分类_id=蓝色’的任何记录,也不会继续到“Products”表,因为该表中没有外键定义。
下面是一个更具体的例子:categories:products:+----+------++----+---------+|id|name||id|name|+----+------++----+---------+|1|red||1|mittens||2|blue||2|boots|+---++------++----+---------+products_categories:+------------+-------------+|product_id|category_id|+------------+-------------+|1|1|//redmittens|1|2|//bluemittens|2|1|//redboots|2|2|//blueboots+------------+-------------+
假设您删除了类别2(蓝色):DELETEFROMcategoriesWHERE(id=2);
DBMS将查看所有具有指向“类别”表的外键的表,并删除匹配id为2的记录。products_categories,删除完成后,您将得到此表:+------------+-------------+|product_id|category_id|+------------+-------------+|1|1|//redmittens|2|1|//redboots+------------+-------------+
中没有定义外键。products表,因此级联将不能在那里工作,所以您仍然有靴子和手套列出。再也没有“蓝色靴子”和“蓝色手套”了。