简体   繁体   中英

mysql Foreign key referencing only part of composite primary key

How to Delete from parent table when Foreign key referencing only part of composite primary key ??

i am using mysql 5.6.2

i have one item table which have primary key item(A,B) and item supplier which have primary key itemsup(A,X,Y) . i have give reference like item(A) = itemsup(A)
When i delete from item(parent) table i get error : 1451 - Cannot delete or update a parent row: a foreign key constraint fails

my table structure is as below.

CREATE TABLE IF NOT EXISTS ITEM ( /* parent */
  ITEMID INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ITEM ID',
  MCA ENUM('A','C','M','X') NOT NULL ,
  ITEMNAME VARCHAR(100) NOT NULL COMMENT 'NAME OF ITEM',
  PRIMARY KEY (ITEMID, MCA)
)
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS ITEMSUP ( /* child */
  ITEMID INT UNSIGNED NOT NULL,
  SUPID INT UNSIGNED NOT NULL,
  MCA ENUM('A','C','M','X') NOT NULL ,
   PRIMARY KEY (ITEMID, SUPID, MCA),
  CONSTRAINT FK_ITEMSUP_ITEM1
    FOREIGN KEY (ITEMID)
    REFERENCES ITEM (ITEMID)
    ON DELETE NO ACTION 
    ON UPDATE CASCADE
 )
ENGINE = InnoDB;

INSERT INTO ITEM (ITEMID, MCA, ITEMNAME) VALUES ( 1,'A', 'ONE A');
INSERT INTO ITEM (ITEMID, MCA, ITEMNAME) VALUES ( 1,'M', 'ONE M');
INSERT INTO ITEMSUP(ITEMID, SUPID, MCA) VALUES(1,1,'X');
/* below is not working */
DELETE FROM ITEM WHERE ITEMID = 1 AND MCA ='A';

http://sqlfiddle.com/#!9/fb961/1

i have found one solution but not sure it right or wrong.

SET FOREIGN_KEY_CHECKS = 0;
DELETE FROM ITEM WHERE ITEMID =1 AND MCA ='A';
SET FOREIGN_KEY_CHECKS = 1;

Why the error message?

In standard SQL a referenced column set must be declared UNIQUE or PRIMARY KEY. MySQL works properly referencing UNIQUE NOT NULL or PRIMARY KEY.

Unfortunately MySQL allows the referenced set to be non-UNIQUE or UNIQUE with NULLs allowed but then doesn't work properly. From the MySQL manual re Using FOREIGN KEY Constraints :

However, the system does not enforce a requirement that the referenced columns be UNIQUE or be declared NOT NULL. The handling of foreign key references to nonunique keys or keys that contain NULL values is not well defined for operations such as UPDATE or DELETE CASCADE. You are advised to use foreign keys that reference only UNIQUE (including PRIMARY) and NOT NULL keys.

In particular from the MySQL manual re InnoDB and FOREIGN KEY Constraints :

If there are several rows in the parent table that have the same referenced key value, InnoDB acts in foreign key checks as if the other parent rows with the same key value do not exist. For example, if you have defined a RESTRICT type constraint, and there is a child row with several parent rows, InnoDB does not permit the deletion of any of those parent rows.

This is why you get the error. Ie you have multiple ITEMID rows with the same row in ITEM.

Adapting your design

Speaking in terms of relational and standard SQL notions, one can only have FOREIGN KEY (ITEMID) REFERENCES ITEM (ITEMID) in ITEMSUP if ITEMID is UNIQUE in ITEM. Since ITEMID is not meant by you to be unique in ITEM, you cannot possibly want a FOREIGN KEY to it. (Informally, ITEMID is not a "key" of ITEM so it can't be a foreign "key" in ITEMSUP.)

To just have every ITEMSUP ITEMID be a value of ITEM ITEMID, make ITEMID PRIMARY KEY of a new table and have a FOREIGN KEY to it from ITEMID and from ITEMSUP (instead of the current ITEMSUP foreign key).

Improving your design

Maybe 'X' is a kind of "null" indicating no MCA and that there doesn't have to be a matching MCS. And/or maybe an ITEMSUP ITEMID's MCA has to match its ITEM MCA when it is non-'X' and/or when it is 'X'. Maybe you just want one MCA per ITEMID in ITEM, in which case change ITEM to have ITEMID PRIMARY KEY and MCA NOT NULL UNIQUE. Maybe ITEM can have multiple ITEMID-MCA pairs but ITEMSUP can only have those ones, in which case have a different ITEMSUP foreign key:

FOREIGN KEY (ITEMID,MCA) REFERENCES ITEM (ITEMID,MCA)

But this would be violated by your SQLFiddle:

INSERT INTO ITEMSUP(ITEMID, SUPID, MCA) VALUES(1,1,'X');

since there is no corresponding subrow (1,'X') in ITEM.

If any "maybe" is true then you have not properly described the constraints on your tables. We can't properly advise on what your design should be unless you confirm exactly what the constraints you need are.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM