복붙노트

[SQL] 외래 키 캐스케이드 여러 경로 및주기의 문제는 무엇인가?

SQL

외래 키 캐스케이드 여러 경로 및주기의 문제는 무엇인가?

SQL Server 2005에서는 그냥 악명 높은 오류 메시지를 강타 :

지금, 나는 이미 (내 경우에는 내가 트리거를 사용해야합니다) 솔루션을 가지고, 그래서 StackOverflow에,이 오류 메시지에 대한 몇 가지 주제를 가지고 있지만, 나는 그런 문제가 전혀 존재 이유에 궁금 하군요.

주기 및 여러 경로 - 내가 알고있는 것처럼, 그들은 피하려는 두 가지 시나리오는 기본적으로있다. 두 개의 테이블이 서로 외래 키 계단식 한 곳주기는 것이다. OK,주기가 너무 여러 테이블에 걸쳐있을 수 있지만, 이것은 기본적인 경우이며, 분석하기 쉬울 것이다.

TableA의 표와 표에 외부 키를 가지고 있으며, 표는 TableC에 외래 키가있는 경우 다중 경로가 될 것입니다. 다시 -이 최소한의 기본 경우입니다.

나는 레코드가 해당 테이블의 삭제 또는 업데이트받을 것이다 때 발생하는 어떤 문제를 볼 수 없습니다. 물론, 당신은 업데이트 / 삭제를해야하는 기록을 확인하기 위해 같은 테이블에 여러 번 쿼리해야 할 수도 있습니다,하지만 그건 정말 문제인가? 이 성능 문제인가?

다른 SO 주제에 사람들은 "캐스케이드 경로를 해결하는 것은 복잡한 문제가"고 "위험"과 국가로 폭포를 사용하여 레이블로까지 이동합니다. 왜? 위험은 어디에 있습니까? 문제는 어디에 있습니까?

해결법

  1. ==============================

    1.하나의 "삭제", 한 "널 (null)": 당신은 같은 부모에서 2 개 캐스케이드 경로와 자식 테이블이있다.

    하나의 "삭제", 한 "널 (null)": 당신은 같은 부모에서 2 개 캐스케이드 경로와 자식 테이블이있다.

    어떤이 우선? 당신은 이후에 무엇을 기대 하는가? 기타

    참고 : 트리거 코드이며, 캐스케이드 일부 정보 또는 조건을 추가 할 수 있습니다.

  2. ==============================

    2.우리가 삭제 캐스케이드를 사용 금지하는 이유는 성능과 잠금과 관련이있다. 당신은 하나 개의 레코드를 삭제하고 조만간 당신이 기록의 큰 그룹을 삭제해야합니다 및 데이터베이스 것 정지에 올 때 네, 그것은 그렇게 나쁘지 않다.

    우리가 삭제 캐스케이드를 사용 금지하는 이유는 성능과 잠금과 관련이있다. 당신은 하나 개의 레코드를 삭제하고 조만간 당신이 기록의 큰 그룹을 삭제해야합니다 및 데이터베이스 것 정지에 올 때 네, 그것은 그렇게 나쁘지 않다.

    당신은 충분히 기록을 삭제하는 경우, SQL Server는 테이블 잠금으로 확대 될 수 있으며 완료 될 때까지 아무도 테이블에 아무것도 할 수 없습니다.

    우리는 최근 자신의 서버에 우리의 클라이언트 중 하나를 옮겼습니다. 거래의 일환으로 우리는 그 클라이언트의 모든 기록은 우리의 원래 서버를 형성 삭제했다. 일괄 그의 모든 정보를 (그래서 다른 사용자와 문제의 원인이 될 수 있습니다) 삭제하면 몇 달을했다. 우리가 삭제 설정을 단계적으로했다면, 데이터베이스 레코드의 수백만이 하나의 트랜잭션에서 삭제 된 트랜잭션이 완료 될 때까지 수백 개의 테이블이 잠겨로 오랜 시간 동안 다른 클라이언트에 액세스 할 수 있었을 것이다.

    또한 교착 상태가 우리가 캐스케이드 경로가 걸렸을 것입니다 우리의 데이터베이스가 다소 clientid는 대부분의 테이블에 나타나는와 비정규 화 된 순서 통제 할 수 없기 때문에 삭제 캐스케이드 사용하여 발생했을 수도 시나리오를 볼 수 있었다. 이 세 번째 테이블뿐만 아니라 differnt 한 경로에 있던 클라이언트 테이블에 외래 키도했다 하나 개의 테이블을 고정 그렇다면이 모든 때문에, 그것은 아마도 세 번째 테이블에서 삭제하려면 해당 테이블을 확인하지 못했습니다 그것을 할 때까지 하나의 트랜잭션과 잠금이 해제되지 않습니다. 그래서 아마도 그것은 거래에서 교착 상태를 만들 수있는 가능성을 본다면 우리는 캐스케이드 삭제를 설정할 수 않았을 것이다.

    모두 삭제를 피하기 위해 또 다른 이유는 때때로 자식 레코드의 존재가 부모 레코드를 삭제하는 것만으로는 충분하지 이유를 것입니다. 당신이 고객 테이블을 가지고 있고 해당 고객이 과거에 주문을 한 경우 예를 들어, 당신은 그를 삭제하고 실제 순서에 대한 정보를 잃고 싶지 않을 것입니다.

  3. ==============================

    3.직원의 테이블을 고려 :

    직원의 테이블을 고려 :

    CREATE TABLE Employee
    (
        EmpID   INTEGER NOT NULL PRIMARY KEY,
        Name    VARCHAR(40) NOT NULL,
        MgrID   INTEGER NOT NULL REFERENCES Employee(EmpID) ON DELETE CASCADE
    );
    
    INSERT INTO Employees(     1, "Bill",   1);
    INSERT INTO Employees(    23, "Steve",  1);
    INSERT INTO Employees(234212, "Helen", 23);
    

    이제 빌의 은퇴를 가정 :

    DELETE FROM Employees WHERE Name = "Bill";
    

    Ooooppps; 모든 사람은 바로 해고되었다!

    [우리는 구문의 세부 정보가 올바른지 여부를 논의 할 수 있습니다; 개념은 내가 생각하는, 의미합니다.]

  4. ==============================

    4.나는 문제는 당신이 다른 "DELETE CASCADE ON"하나 개의 경로를 할 때, 또는 "NO ACTION"결과 (결과가) 예기치 못한입니다 "ON, 제한 삭제"고 생각합니다. 그것은 (이것은 또한 트리거,하지만 당신은 자신을 구축 할 필요가 없습니다 하나)하는 삭제 트리거에 따라 먼저 실행됩니다.

    나는 문제는 당신이 다른 "DELETE CASCADE ON"하나 개의 경로를 할 때, 또는 "NO ACTION"결과 (결과가) 예기치 못한입니다 "ON, 제한 삭제"고 생각합니다. 그것은 (이것은 또한 트리거,하지만 당신은 자신을 구축 할 필요가 없습니다 하나)하는 삭제 트리거에 따라 먼저 실행됩니다.

  5. ==============================

    5.그 폭포는 "위험"것을 피해야한다에 동의합니다. (나는 개인적으로 가진 SQL 서버가 자동으로 돌볼 것을 수동으로 오히려 변화를 계단식 선호). 이는 SQL 서버가 수백만 개의 행을 삭제하는 경우에도, 출력은 여전히으로 표시하기 때문이기도하다

    그 폭포는 "위험"것을 피해야한다에 동의합니다. (나는 개인적으로 가진 SQL 서버가 자동으로 돌볼 것을 수동으로 오히려 변화를 계단식 선호). 이는 SQL 서버가 수백만 개의 행을 삭제하는 경우에도, 출력은 여전히으로 표시하기 때문이기도하다

    (1 개 행 적용됨)

  6. ==============================

    6.나는 DELETE CASCADE 옵션을 ON a를 구현하는 비즈니스 모델의 문제이다 사용 여부를 생각합니다. 두 비즈니스 개체의 관계는 단순한 관계 양단 관련된 "연관"하지만, 그 독립 개체 및 기타 다른 로직에 의해 제어되는 하나의주기 일 수있다. 하나의 개체가 실제로 "부모"또는 "아이"의 "소유자"또는 "세부"개체로 볼 수 있습니다 "통합"의 관계는, 또한, 그러나있다. 개체 부만으로 다수의 조성물로 존재하는 "조성물"관계의 더 강한 개념이있다. 은 "협회"경우에, 당신은 일반적으로 ON DELETE CASCADE 제약 조건을 선언하지 않습니다. 집계 또는 조성물의 경우, 그러나, ON DELETE CASCADE는 더 정확하게 데이터베이스에 비즈니스 모델을 매핑하고 선언적인 방법에 도움이됩니다. 그것은 MS SQL 서버는 단일 캐스케이드 경로로이 옵션의 사용을 제한하는 날 귀찮게하는 이유입니다. 제가 잘못 본게 아니라면, 다른 많은 널리 사용되는 SQL 데이터베이스 시스템은 제한을 부과하지 않습니다.

    나는 DELETE CASCADE 옵션을 ON a를 구현하는 비즈니스 모델의 문제이다 사용 여부를 생각합니다. 두 비즈니스 개체의 관계는 단순한 관계 양단 관련된 "연관"하지만, 그 독립 개체 및 기타 다른 로직에 의해 제어되는 하나의주기 일 수있다. 하나의 개체가 실제로 "부모"또는 "아이"의 "소유자"또는 "세부"개체로 볼 수 있습니다 "통합"의 관계는, 또한, 그러나있다. 개체 부만으로 다수의 조성물로 존재하는 "조성물"관계의 더 강한 개념이있다. 은 "협회"경우에, 당신은 일반적으로 ON DELETE CASCADE 제약 조건을 선언하지 않습니다. 집계 또는 조성물의 경우, 그러나, ON DELETE CASCADE는 더 정확하게 데이터베이스에 비즈니스 모델을 매핑하고 선언적인 방법에 도움이됩니다. 그것은 MS SQL 서버는 단일 캐스케이드 경로로이 옵션의 사용을 제한하는 날 귀찮게하는 이유입니다. 제가 잘못 본게 아니라면, 다른 많은 널리 사용되는 SQL 데이터베이스 시스템은 제한을 부과하지 않습니다.

  7. from https://stackoverflow.com/questions/1637708/what-is-the-problem-with-foreign-key-cascade-multiple-paths-and-cycles by cc-by-sa and MIT license