Multiple Column Foreign Key: Set single column to Null “ON DELETE” instead of all

后端 未结 1 1799
野的像风
野的像风 2021-01-14 21:30

General: Given a foreign key over several columns, some of them might be NULL.
By default (MATCH SIMPLE) MySQL/MariaDB InnoDB does not check the foreign

相关标签:
1条回答
  • 2021-01-14 22:16

    After some research it seems like that particular requirement is not implementable using foreign keys.

    The best solution seems to be using a mix of Foreign Keys and a Trigger.

    The problem can be solved for the given example by the following statements:

    CREATE TABLE lectures (
      lectureId INT NOT NULL,
      title VARCHAR(10) NOT NULL,
      PRIMARY KEY (lectureId)
     );
    
    CREATE TABLE groups (
      lectureId INT NOT NULL,
      groupNo INT NOT NULL,
      title VARCHAR(10) NOT NULL,
      PRIMARY KEY (lectureId,groupNo),
      FOREIGN KEY (lectureId) REFERENCES lectures (lectureId)
        ON UPDATE CASCADE ON DELETE CASCADE
     );
    
    CREATE TABLE studentListed (
      studentId INT NOT NULL,
      lectureId INT NOT NULL,
      groupNo INT NULL,
      PRIMARY KEY (studentId,lectureId),
      FOREIGN KEY (lectureId) REFERENCES lectures (lectureId) 
        ON UPDATE CASCADE ON DELETE CASCADE,
      FOREIGN KEY (lectureId,groupNo) REFERENCES groups (lectureId,groupNo)
        ON UPDATE CASCADE ON DELETE CASCADE
     );
    
    CREATE TRIGGER GroupDelete BEFORE DELETE ON groups
    FOR EACH ROW
      UPDATE studentListed SET studentListed.groupNo = NULL
        WHERE studentListed.lectureId = OLD.lectureId
        AND studentListed.groupNo = OLD.groupNo;
    

    Note that the "ON DELETE CASCADE" of the last foreign key will never lead to a cascaded delete as the Trigger already removed the foreign key references by null-ing the corresponding rows.

    Addition: Instead of using "ON DELETE CASCADE" one could use "ON DELETE SET NULL" with the same trigger, but then "lectureId" has to be nullable and one should include a "CHECK (lectureId IS NOT NULL)" to ensure it is never set to null

    0 讨论(0)
提交回复
热议问题