계단식 (ON DELETE / UPDATE) 동작에 대한 설명


98

나는 매일 스키마를 디자인하지 않지만 그렇게 할 때 관리를 쉽게하기 위해 계단식 업데이트 / 삭제를 올바르게 설정하려고합니다. 캐스케이드 작동 방식을 이해하지만 어느 테이블이 어느 것인지 기억할 수 없습니다.

예를 들어, 나는 두 개의 테이블이 - ParentChild의 외래 키와 - Child그 참조 Parent하고있다 ON DELETE CASCADE캐스케이드를 트리거 기록하고있는이 폭포에 의해 삭제 얻을 기록,? 내 첫번째 추측은 될 Child기록이 때 삭제 얻을 Parent레코드가 삭제되기 때문에, Child기록에 따라 Parent기록하지만,이 ON DELETE모호; 그것은 삭제 의미 할 수 Parent때 기록을 Child기록 삭제, 또는 삭제 의미 할 수 Child이 때 기록이 Parent삭제됩니다. 그래서 어느 것입니까?

나는 구문이 있었으면 ON PARENT DELETE, CASCADE, ON FOREIGN DELETE, CASCADE또는 모호성을 제거 비슷한. 누구든지 이것을 기억하는 니모닉이 있습니까?

답변:


138

당신이 좋아하는 경우 ParentChild조건을 당신이 그들이 기억하기 쉬운 느낌, 당신의 번역했습니다 ON DELETE CASCADE에를Leave No Orphans!

즉, Parent행이 삭제 (종료) 될 때 Child테이블 에 고아 행이 활성 상태로 남아 있으면 안됩니다 . 부모 행의 모든 ​​자식도 삭제 (삭제)됩니다. 이 자식 중 하나가 손자 (다른 외래 키를 통해 다른 테이블에 있음)를 가지고 있고 ON DELETE CASCADE정의 된 경우, 자식도 함께 종료해야합니다 (연쇄 효과가 정의되어있는 한 모든 자손).

FOREIGN KEY제약 자체로도 설명 할 수있다 Allow No Orphans!(처음부터). 아니 Child그것은하지 않은 경우 지금까지 허용해야 자식 테이블에 (기록 없음) Parent(부모 테이블에서 행을).

일관성을 유지 ON DELETE RESTRICT하기 위해를 (덜 공격적)으로 변환 할 수 있습니다. You Can't Kill Parents!자식이없는 행만 종료 (삭제) 할 수 있습니다.


3
나는 여전히 비유에서 무언가가 빠져 있다고 느낍니다. 자녀가 둘 이상의 부모를 가질 수 없습니까? 이 경우 한 부모를 죽이면 아이를 고아로 만들 수 있습니까?
Jus12

7
@ Jus12 아니요, 외래 키 제약 조건은 부모 1 명에서만 작동합니다. 이 측면과 관련하여 좋은 비유는 아닙니다.
ypercubeᵀᴹ

1
@ ypercube : 허용되지 않습니까? Order(custID, itemID, orderID)여기서 테이블 custID의 기본 키를 Customers나타내고 테이블 의 기본 키를 itemID나타냅니다 Items. 하지 않음 Order이 부모가?
Jus12

4
@ Jus12 물론 허용되지만 2 개의 외래 키 제약 조건이됩니다. 그런 다음 모든 어린이 (주문)에는 부모 (고객)와 부모 (항목)가 있습니다. 두 FK의 동작은 다를 수 있습니다. (예를 들어, 고객을 죽이는 것은 그들의 모든 (주문) 아이들을 죽일 것이지만 아이템을 죽이는 것은 그들의 주문을 죽이지 않을 수도 있습니다.)
ypercubeᵀᴹ

1
우리가 "고아"라고 말하지 않으면 부모의 비유는 여전히 효과가 있습니다. 자녀 항목에 별도의 두 부모에 대한 언급이 두 개인 경우에도 이혼 한 부부의 자녀로 볼 수 있습니다. 제한 : "나는 당신이 엄마를 죽이지 못하게"캐스케이드 : "당신이 아빠를 죽이면 나도 죽을 것이다"
Christopher McGowan

31

예를 들어, 부모 레코드가 자식 레코드를 소유하는 두 개의 테이블 (부모 및 자식)이있는 경우 어떤 테이블에 ON DELETE CASCADE가 필요합니까?

ON DELETE CASCADE는 외래 키 선언의 선택적 절입니다. 외래 키 선언도 마찬가지 입니다 . ( "자식"표의 의미)

... 자식 레코드가 삭제 될 때 부모 레코드를 삭제하거나 부모가 삭제 될 때 자식 레코드를 삭제하는 것을 의미 할 수 있습니다. 그래서 어느 것입니까?

외래 키 선언을 해석하는 한 가지 방법은 "이 열에 유효한 모든 값은 'that_table'의 'that_column'에서 온 것입니다." "자식"테이블에서 행을 삭제하면 아무도 신경 쓰지 않습니다. 데이터 무결성에 영향을 미치지 않습니다.

"부모"테이블에서 "that_table"에서 행을 삭제하면 "자식"테이블의 가능한 값에서 유효한 값이 제거됩니다. 데이터 무결성을 유지하기 위해, 당신은해야 할 은 "아이"테이블을. 계단식 삭제는 할 수있는 일 중 하나입니다.


2

SQL : 2011 사양

이 다섯 개 옵션이 있습니다 ON DELETE, 그리고 ON UPDATE그것은에 적용 할 수 있습니다 FOREIGN KEY. 이것들은 <referential actions>SQL : 2011 스펙에서 직접 호출 됩니다.

  • ON DELETE CASCADE: 참조 된 테이블의 행이 삭제되면 참조 테이블의 일치하는 모든 행이 삭제됩니다.
  • ON DELETE SET NULL: 참조 테이블의 행이 삭제되면 참조 테이블의 모든 일치하는 행의 모든 ​​참조 열이 널로 설정됩니다.
  • ON DELETE SET DEFAULT: 참조 테이블의 행이 삭제되면 참조 테이블의 모든 일치하는 행의 모든 ​​참조 열이 열의 기본값으로 설정됩니다.
  • ON DELETE RESTRICT: 참조 테이블에 해당 행이 일치하는 행이 있으면 참조 테이블의 행을 삭제할 수 없습니다.
  • ON DELETE NO ACTION (기본값) : 참조 삭제 동작이 없습니다. 참조 제한 조건은 제한 조건 점검 만 지정합니다.

외래 키는 종속 관계를 설정합니다. <referential action>관계가 해산 될 때 발생 하는 사항을 결정합니다.

예 / 은유 / 설명

모든 어디 :이 예를 들어, 우리는 사회와 경제의 일반적인 모델을 수락 business받는 관계를 유지하는 회사입니다 bourgeoisie스루 fatcat_owner.

CREATE TABLE bourgeoisie(
  fatcat_owner varchar(100) PRIMARY KEY
);
INSERT INTO bourgeoisie(fatcat_owner) VALUES
  ( 'Koch Brothers' );

CREATE TABLE business (
  name         varchar(100),
  fatcat_owner varchar(100) REFERENCES bourgeoisie
);
INSERT INTO business(name, fatcat_owner)
  VALUES ('Georgia-Pacific', 'Koch Brothers');

모든 businessES가 bourgeoisie그들 에 의해 직접 영향을받는 다면 fatcat_owner, 노동자 혁명 이후에 당신은 fatcat_owner사회 를 정화하고 계급없는 사회를 가질 때 무엇을합니까?

-- Viva la revolución 
BEGIN;
  DELETE FROM bourgeoisie;
END;

여기 몇 가지 옵션이 있습니다.

  • 혁명을 멈추십시오. SQL 용어에서 RESTRICT. 어떤 사람들은 이것이 덜 악하다고 생각하지만 보통 잘못입니다.
  • 계속 진행하십시오. 그렇다면 혁명이 일어날 때 SQL은 네 가지 옵션을 제공합니다.

    • SET NULL-비워 두십시오. 누구가 알고 있는지, 어쩌면 자본주의는이 복원 bourgeoisie나타나고 과두 지배 세력은의 롤을 채우기 fatcat_owners. 중요한 점은 열 이 NULLABLE아니 어야하며 그렇지 않을 NOT NULL수 있습니다.
    • SET DEFAULT아마도 당신은 DEFAULT이것을 처리 했습니까? A는 DEFAULT함수를 호출 할 수 있습니다. 아마도 당신의 스키마는 이미 혁명 준비가되어있을 것입니다.
    • CASCADE-데미지 컨트롤이 없습니다. (가)되면 bourgeoisie간다, 그래서 않습니다 business. 비즈니스에 있어야하는 경우 비즈니스 fatcat_pig 아닌 business테이블 에있는 것보다 데이터를 잃는 것이 더 의미가있는 경우가 있습니다 .
    • NO ACTION-이것은 본질적으로 검사를 지연시키는 방법입니다 .MySQL에서는 다르지 RESTRICT않지만 PostgreSQL에서는 할 수 있습니다.

      -- Not a real revolution.
      -- requires constraint be DEFERRABLE INITIALLY DEFERRED
      BEGIN;
        SET CONSTRAINTS ALL DEFERRED;
        DELETE FROM bourgeoisie;
        INSERT INTO bourgeoisie VALUES ( 'Putin' );
        UPDATE business SET fatcat_pig = 'Putin';
      END;

      이러한 시스템에서 제한 조건은 트랜잭션이 커미트되기 전에 만 유효성 검증됩니다. 이로 인해 혁명이 멈출 수 있지만 어느 정도의 "복구"를 위해 트랜잭션을 복구 할 수 있습니다.


합니까 referenced테이블이 부모 테이블을 의미하고, referencing테이블 자식 테이블을 의미?
sg552

@ sg552 예, 올바르게 이해했습니다.
informatik01

0

간단한 니모닉은

상위 CASCADE의 ON DELETE [삭제]

어떤 삭제 (부모 삭제)가 계단식으로 연결되는지, ON DELETE CASCADE 문이 (자식에서)가는 곳 과 삭제되는 항목 (자식)이 나타납니다.


-3

아마도 우리는 구문을 합리화 할 수 있습니다. 파이썬 예제를 보자 :

class Parent(self):
    # define parent's fields

class Child(self):    
    # define child's fields
    parent_pk_is_childs_foreign_key = models.ForeignKey(Parent, on_delete=models.CASCADE)

이 줄에 표시된 것은 부모의 on_delete입니다 (명세서에서 실수로 언급 됨). 삭제를 하위 항목에 계단식으로 넣으십시오. 이것이 CASCADE 문이 하위 레벨에서 정의되는 이유이므로 삭제해야하는 하위를 표시합니다.

예를 들어 다른 수업이있는 경우

class GrownUpChild(self):    
        # define grown up child's fields
        parent_pk_is_childs_foreign_key = models.ForeignKey(Parent, on_delete=models.DO_NOTHING)

이 구조는 어떤 어린이가 제거되어야하는지 (어린이), 고아 임에도 불구하고 (GrownUpChild) 유지해야하는 것을 명확하게 보여줍니다.

[편집 : 토론의 맥락, 특히 on_delete = models.CASCADE 등의 경우를 고려할 때] 사실 감사 및보고 이유와 우발적 인 복구로 인해 삭제 된 부모의 자녀를 떠나는 것이 바람직한 행동입니다. 삭제. [물론 엔터프라이즈 급 소프트웨어는 이러한 동작을 중심으로 작성되며 삭제 된 레코드를 실제로 삭제하는 대신 삭제 된 것으로 표시합니다. 또한 특별히 설계된 보고서를 제외한 프런트 엔드에 대한 쿼리에는 포함하지 않습니다. 또한 데이터베이스에서 deleted == 1 레코드를 제거하는 기능이 있으며, 일반적으로 UI 관리자가 실행하며 종종 데이터베이스 관리자 측의 개입을 피합니다.]


1
'사실은 실수로 삭제 한 내용을 복구 할뿐만 아니라 감사 및보고 이유 때문에 삭제 된 부모의 자녀를 떠나는 것이 바람직한 행동 입니다.
dezso

귀하의 의견에 감사드립니다. 그러나 여러 엔터프라이즈 급 CRM 시스템이이를 정확히 수행합니다.
George Mogilevsky

TBH는 더 이상 합리적이지 않습니다. 나는 한 번 그런 접근 방식으로 인한 똥을 해결하라는 임무를 받았습니다. 월급을 제외하고는 기쁨이 없습니다.
dezso

당신은 정통한 데이터베이스 관리자처럼 들린다 :) 나는 당신의 요점을 완전히들을 수 있습니다. 위에서 언급 한 소프트웨어는 실제로 삭제 된 = 1을 수동으로 제거하는 기능을 가지고 있으므로이 전화를하는 것은 앱 관리자에게 달려 있습니다. 일반적으로 데이터베이스 관리자는이 측면을 유지 관리하는 데 관여하지 않습니다. 게다가, 전체 소프트웨어의 데이터베이스 클래스는 개념을 중심으로 구축되므로 항상 crud 작업에서 삭제 된 플래그를 검사합니다
George Mogilevsky

그렇습니다. 이것은 잘 알려져 있고 제정신입니다. 그러나이를 반영하기 위해 위의 문구를 변경해야합니다.
dezso
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.