programing

다중 열 외부 키: 단일 열을 모두가 아닌 Null "ON DELETE"로 설정합니다.

minecode 2022. 10. 22. 21:30
반응형

다중 열 외부 키: 단일 열을 모두가 아닌 Null "ON DELETE"로 설정합니다.

일반: 외부 키가 여러 열에 걸쳐 있으면 일부 키가 NULL일 수 있습니다.
기본적으로 (MATCH SIMPLE) MySQL/MariaDB InnoDB는 여러 열의 외부 키가 NULL인 한 외부 키를 확인하지 않습니다.

요건: 부모에서 행을 삭제한 경우, 대응하는 자식의 1열은 NULL로 설정해야 합니다.단, 외부 키의 2열 모두 NULL로 설정할 수 없습니다.

예/설명:학생이 강의에 등록될 수도 있고 선택적으로 강의 그룹 중 하나에 등록될 수도 있습니다.강의가 삭제되면 모든 학생 목록(작업)과 모든 해당 그룹(작업)을 제거해야 합니다.1개의 그룹만 삭제해도 수강생은 등록되지만 더 이상 그룹에 할당되지 않습니다(문제).

예/SQL: 다음 SQL은 이 예를 제시하지만 마지막 FORENAL KEY는 모두 NULL 가능해야 하지만, 두 개의 NULL 가능을 모두 지정하면 그룹을 삭제하면 teleCTId도 NULL로 설정됩니다.

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 SET NULL
 );

몇 가지 조사 결과, 이 특정 요건은 외부 키를 사용하여 구현할 수 없는 것으로 보입니다.

가장 좋은 해결책은 외부 키와 트리거함께 사용하는 것 같습니다.

이 문제는 다음 문장으로 해결할 수 있습니다.

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;

마지막 외부 키의 "ON DELETE CASCADE"는 트리거가 대응하는 행을 늘링하여 외부 키 참조를 이미 삭제했기 때문에 계단식 삭제로 이어지지 않습니다.

추가:"ON DELETE CASCADE"를 사용하는 대신 동일한 트리거에 "ON DELETE SET NULL"을 사용할 수 있지만 "leCTureId"는 NULL이 되어야 하며 "CHECK (lectureId IS NOT NULL)"를 포함하여 NULL로 설정되지 않도록 해야 합니다.

언급URL : https://stackoverflow.com/questions/33735266/multiple-column-foreign-key-set-single-column-to-null-on-delete-instead-of-al

반응형