mysql에서 On Delete Cascade와 On Update Cascade의 차이점


45

나는 MySQL의 데이터베이스 - 두 개의 테이블이 parent,을 child. 부모 테이블을 기반으로 자식 테이블에 외래 키 참조를 추가하려고합니다. ON UPDATE CASCADE와 사이에 큰 차이가 있습니까?ON DELETE CASCADE

내 부모님 테이블

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

내 질문은 : 다음 SQL 쿼리의 차이점은 무엇입니까?

  1. ON DELETE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON DELETE CASCADE
    ) ENGINE=INNODB;
  2. ON UPDATE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON UPDATE CASCADE
    ) ENGINE=INNODB;
  3. ON UPDATE CASCADE ON DELETE CASCADE

    CREATE TABLE child (
            id INT, 
            parent_id INT,
            INDEX par_ind (parent_id),
            FOREIGN KEY (parent_id) 
                REFERENCES parent(id)
                ON UPDATE CASCADE ON DELETE CASCADE
        ) ENGINE=INNODB;

쿼리에 오류가 있습니까? 이 쿼리 (1,2 & 3)는 무엇을 의미합니까? 그들은 같은가요 ???


1
ps <nitpick> 완전성에 대해 위에서 이야기 한 것은 쿼리가 아닌 DDL (Data Definition Language) 입니다. 검색어는 일반적으로 DML (데이터 조작 언어 SELECT, INSERT, UPDATE, DELETE)로 간주됩니다. </ nitpick>
Vérace

완전성을위한 또 다른 ps는 기본값이 무엇인지 궁금합니다. 그래서 나는 업데이트 또는 삭제가없는 자식을 만들었습니다. 그러면 종속 자식이있는 부모를 업데이트하거나 삭제할 수 없습니다. 그러나 완벽한 의미는 있지만, MySQL이 항상 특정 특성의 모델은 아닙니다. :-)
Vérace

답변:


64

이 주제에 대한 아주 좋은 실이 여기여기에 있습니다 . MySQL에 대한 결정적인 가이드는 물론 여기 에서 찾을 수있는 문서 입니다.

SQL 2003 표준에는 5 가지 다른 참조 동작이 있습니다.

  1. 종속
  2. 얽매다
  3. 조치 없음
  4. NULL 설정
  5. 기본값으로 설정

질문에 대답하려면 :

  1. 종속

    • ON DELETE CASCADE부모 레코드가 삭제되면 모든 자식 레코드도 삭제됩니다. 이것은 제 생각에는 좋은 생각 이 아닙니다 . TRIGGERs를 사용하여 수행 할 수 있지만 데이터베이스에있는 모든 데이터를 추적해야합니다 . (그러나 아래의 주석에서주의 사항을 참조하십시오).

    • ON UPDATE CASCADE부모 기본 키가 변경되면 자식 값도이를 반영하도록 변경됩니다. 다시 말하지만, 좋은 생각은 아닙니다. PRIMARY KEY규칙 성 또는 전혀 변경 하지 않으면 디자인에 문제가 있습니다. 다시, 의견을보십시오.

    • ON UPDATE CASCADE ON DELETE CASCADE귀하 UPDATE 또는 DELETE 부모 인 경우 변경 사항이 하위 항목에 연계됨을 의미합니다. 이것은 AND처음 두 진술의 결과 와 동일 합니다.

  2. 얽매다

    • RESTRICT부모를 삭제 및 / 또는 업데이트하려고하면 오류가 발생하지 않습니다. 이는 참조 조치가 명시 적으로 지정되지 않은 경우의 기본 동작입니다.

      위해 ON DELETE또는 ON UPDATE그 지정하지 않으면 기본 동작은 항상 RESTRICT`입니다.

  3. 조치 없음

    • NO ACTION다음에서 수동 . 표준 SQL의 키워드입니다. MySQL에서는에 해당합니다 RESTRICT. 참조 테이블에 관련 외래 키 값이있는 경우 MySQL 서버는 상위 테이블에 대한 삭제 또는 업데이트 작업을 거부합니다. 일부 데이터베이스 시스템은 지연된 검사를 가지고 NO ACTION있으며 지연된 검사입니다. MySQL에서는 외래 키 제약 조건이 즉시 확인되므로 NO ACTION와 동일합니다 RESTRICT.
  4. NULL 설정

    • SET NULL-매뉴얼에서 다시. 부모 테이블에서 행을 삭제하거나 업데이트하고 자식 테이블의 외래 키 열을로 설정하십시오 NULL. 이것은 "시간 여행"방법이 없기 때문에 가장 좋은 아이디어는 아닙니다. 즉, 하위 테이블을 되돌아보고 NULL관련 상위 레코드와 레코드를 연관 시키 CASCADE거나 TRIGGERs를 사용 하여 로깅 테이블을 채워 추적합니다. 변경 사항 (그러나 주석 참조).
  5. 기본값으로 설정

    • SET DEFAULT. MySQL이 구현을 방해하지 않는 SQL 표준의 또 다른 (잠재적으로 유용한) 부분! 개발자가 UPDATE 또는 DELETE에서 외래 키 열을 설정할 값을 지정할 수 있습니다. InnoDB와 NDB는 SET DEFAULT절을 사용하여 테이블 정의를 거부합니다 .

위에서 언급했듯이 여기 에서 문서를 살펴 보는 데 약간의 시간이 소요 됩니다 .


8
나는 당신의 완전한 대답을 좋아하지만이 진술에 동의하지 않습니다. "데이터베이스에 있었던 모든 데이터를 추적해야합니다."-데이터베이스의 설계 및 목적에 따라 달라집니다. 예를 들어, 레시피 정의가 삭제 될 때 레시피 정의 (시스템 구성과 유사하게 음식을 말하고 있지 않습니다)는 해당 레시피의 관련 하위를 유지하는 것이 의미가 없습니다. 기계 시스템을위한 작업 테이블 – 더 이상 데이터가 필요하지 않습니다. 처리하고 제거하십시오. 그 이외의 대답은 환상적입니다.
StixO

2
@StixO와 비슷하지만이 답변은 대부분 마음에 들지만 기본 키 변경에 동의하지 않아야합니다. 이것이 나쁜 아이디어가 될 디자인은 분명히 있지만 분산 데이터베이스에 들어가면 레코드의 ID를 잃지 않고 기본 키를 자유롭게 다시 할당하는 것이 매우 바람직 할 수 있습니다.
Garet Claborn

"제 생각에는 좋은 생각이 아닙니다. 데이터베이스에있는 모든 데이터를 추적해야합니다." -당신의 요점을 이해하지 못합니다. '삭제시'계단식으로 연결된 경우 이미 무언가를 삭제하기로 결정했습니다. 아무것도 삭제하지 않기로 결정한 경우에는 계단식으로 진행되지 않습니다. 그래도 응용 프로그램에서 외국 ID가있는 레코드를 찾을 때 레코드가 있음을 알 수 있으며 삭제하기로 결정하면 데이터베이스를 부 풀리는 고아 행이 없다는 것을 확신 할 수 있다는 것입니다 어떤 것.
Jeff Ryan

여기의 논리는 장소에서 꽤 잘못되었으며 새로운 GDPR 세계에서 훨씬 더 잘못되었습니다. 기본 키가 변경되면 문제가 있음을 나타내는 개념에 동의합니다.
척 레 버트

기본 키를 규칙적으로 또는 전혀 바꾸지 않으면 디자인에 문제가있는 것입니다. ON UPDATE CASCADE가 키 값 또는 키 이름을 변경한다는 의미입니까?
Billal Begueradj

8

이 두 가지는 상위 테이블에서 참조 된 레코드가 ID를 변경하고 삭제 될 때 각각 수행되는 조치입니다.

당신이 실행하는 경우 :

UPDATE parent SET id = -1 WHERE id = 1;

그리고 적어도 하나의 레코드가 child있습니다 parent_id = 1. 1) 실패합니다. 2) 및 3)의 경우, parent_id = 1 인 모든 레코드는 parent_id = -1로 업데이트됩니다.

당신이 실행하는 경우 :

DELETE FROM parent WHERE id = 1;

에 적어도 하나의 레코드가 child있습니다 parent_id = 1. 2) 실패합니다. 1) 및 3)의 경우 모든 레코드 parent_id = 1가 삭제됩니다.

3) 문법적으로 정확합니다.

전체 설명서 는 매뉴얼에서 찾을 수 있습니다 .


6

이전 답변에 대해 언급 할만한 명성이 없습니다. 그래서 조금 정교하게 생각했습니다.

1) ON DELETE CASCADE는 상위 레코드가 삭제되면 참조하는 하위 레코드도 삭제됨을 의미합니다. ON UPDATE의 기본값은 RESTRICT입니다. 즉, 상위 레코드의 UPDATE가 실패합니다.

2) ON DELETE 조치의 기본값은 RESTRICT입니다. 이는 상위 레코드의 DELETE가 실패 함을 의미합니다. ON UPDATE CASCADE는 상위 레코드가 업데이트 될 때 모든 참조 하위 레코드를 업데이트합니다.

3) 위의 1) 및 2)의 CASCADE 조치를 참조하십시오.

부모 레코드 ID를 외래 키로 사용하는 경우 (자식 테이블에서)-경험에 따르면 a) ID가 자동 생성 된 시퀀스 번호 인 경우 외래 키로 사용하지 마십시오. 다른 고유 한 상위 키를 대신 사용하십시오. b) ID가 GUID이면 외래 키로 사용할 수 있습니다. 레코드를 내보내거나 가져 오거나 다른 데이터베이스로 레코드를 복사 할 때이 제안에 대한 지혜가 나타납니다. 외래 키로 참조 될 때 데이터 마이그레이션 중에 자동 생성 된 시퀀스 번호를 처리하는 것은 너무 번거 롭습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.