SQL Server에서 외래 키를 설정할 때 어떤 상황에서 삭제 또는 업데이트시 계단식으로 연결해야하며 그 이유는 무엇입니까?
이것은 아마도 다른 데이터베이스에도 적용됩니다.
나는 각 시나리오의 구체적 예를 위해 무엇보다도 가장 바람직하게 그것을 사용하는 사람으로부터 찾고 있습니다.
SQL Server에서 외래 키를 설정할 때 어떤 상황에서 삭제 또는 업데이트시 계단식으로 연결해야하며 그 이유는 무엇입니까?
이것은 아마도 다른 데이터베이스에도 적용됩니다.
나는 각 시나리오의 구체적 예를 위해 무엇보다도 가장 바람직하게 그것을 사용하는 사람으로부터 찾고 있습니다.
답변:
지금까지 본 내용 요약 :
외래 키는 데이터베이스의 참조 무결성을 보장하는 가장 좋은 방법입니다. 마술이기 때문에 캐스케이드를 피하는 것은 컴파일러의 마술을 신뢰하지 않기 때문에 모든 것을 어셈블리에 쓰는 것과 같습니다.
나쁜 것은 외래 키를 뒤로 만드는 것과 같이 외래 키를 잘못 사용한다는 것입니다.
Juan Manuel의 예제는 정식 예제입니다. 코드를 사용하면 데이터베이스에 가짜 DocumentItem을 남길 가능성이 더 높습니다.
계단식 업데이트는 예를 들어 사용자 테이블의 기본 키가 이름, 성 조합과 같이 변경할 수있는 것으로 데이터를 참조 할 때 유용합니다. 그런 다음 해당 조합의 변경 사항이 참조되는 곳으로 전파되기를 원합니다.
@Aidan, 당신이 말하는 그 명확성은 비용이 많이 들지 않습니다 . 데이터베이스에 가짜 데이터를 남길 수 있습니다 . 저에게는 보통 DB에 익숙하지 않으며 DB를 사용하기 전에 어떤 FK가 있는지 파악할 수 없기 때문에 그러한 두려움이 생깁니다. 개체가 개념적으로 관련되지 않았거나 역사를 보존 해야하는 곳에서 캐스케이드를 계속 사용하거나 연속적으로 잘못 사용합니다.
계단식 삭제를 사용하지 않습니다.
데이터베이스에서 무언가를 제거하려면 원하는 것을 데이터베이스에 명시 적으로 말하고 싶습니다.
물론 그것들은 데이터베이스에서 사용할 수있는 함수이며, 'order'테이블과 'orderItem'테이블이있는 경우 데이터베이스를 삭제할 때 항목을 지우고 싶을 때 사용할 수 있습니다. 주문.
나는 '매직'이 아닌 코드 (또는 저장 프로 시저)에서 수행하는 명확성을 좋아합니다.
같은 이유로 나는 트리거 팬도 아닙니다.
주의 할 점은 '주문'을 삭제하면 계단식 삭제에서 'orderItem'이 50 개를 제거하더라도 '1 행 영향'보고서가 다시 표시됩니다.
계단식 삭제로 많은 작업을 수행합니다.
데이터베이스에 대해 작업하는 사람이 원치 않는 데이터를 남기지 않을 수 있다는 것을 아는 것이 좋습니다. 종속성이 커지면 Management Studio의 다이어그램에서 제약 조건을 변경하기 때문에 sp 또는 데이터 액세스를 조정할 필요가 없습니다.
즉, 계단식 삭제와 순환 참조에는 1 가지 문제가 있습니다. 이는 계단식 삭제가없는 데이터베이스 부분으로 이어지는 경우가 많습니다.
많은 데이터베이스 작업을 수행하고 계단식 삭제가 유용한 경우는 거의 없습니다. 내가 효과적으로 사용한 것은 야간 작업에 의해 업데이트되는보고 데이터베이스에 있습니다. 마지막 가져 오기 이후에 변경된 최상위 레코드를 삭제 한 다음 수정 된 레코드 및 관련 레코드를 다시 가져 와서 변경된 데이터를 올바르게 가져옵니다. 데이터베이스의 맨 아래에서 맨 위까지 보이는 많은 복잡한 삭제를 작성하지 않아도됩니다.
캐스케이드 삭제는 데이터를 삭제하기 때문에 트리거만큼 나쁘지 않다고 생각하지 않습니다. 트리거에는 모든 종류의 불쾌한 물건이 포함될 수 있습니다.
일반적으로 실제 삭제를 피하고 논리적 삭제 (즉, isDeleted라는 비트 열이 true로 설정 됨)를 대신 사용하십시오.
과거의 나쁜 경험으로 인해 "On Delete Cascade"(및 기타) 사용을 금지하는 DBA 및 / 또는 "회사 정책"에 대해 들었습니다. 어떤 경우에는 한 남자가 서로를 부르는 세 가지 방아쇠를 썼습니다. 하나의 idjit의 조치로 인해 복구 3 일 동안 트리거가 완전히 금지되었습니다.
물론 일부 하위 데이터를 보존해야하는 경우와 같이 "삭제시 계단식"대신 트리거가 필요합니다. 그러나 다른 경우에는 On Delete 캐스케이드 방법을 사용하는 것이 완벽하게 유효합니다. "삭제시 계단식"의 주요 장점은 모든 하위 항목을 캡처한다는 것입니다. 사용자 지정 작성 트리거 / 저장 프로 시저가 올바르게 코딩되지 않으면 그렇지 않을 수 있습니다.
개발자는 개발 내용과 사양에 따라 결정을 내릴 수 있어야한다고 생각합니다. 나쁜 경험에 근거한 카펫 금지는 기준이되어서는 안됩니다. "절대 사용하지 않음"사고 과정은 드라코 니안입니다. 매번 판단 호출이 필요하며 비즈니스 모델이 변경됨에 따라 변경됩니다.
이것이 개발의 전부가 아닙니까?
코드에서 수행하지 않고 연속 삭제를 수행하는 한 가지 이유는 성능을 향상시키기위한 것입니다.
사례 1 : 계단식 삭제
DELETE FROM table WHERE SomeDate < 7 years ago;
사례 2 : 계단식 삭제없이
FOR EACH R IN (SELECT FROM table WHERE SomeDate < 7 years ago) LOOP
DELETE FROM ChildTable WHERE tableId = R.tableId;
DELETE FROM table WHERE tableId = R.tableid;
/* More child tables here */
NEXT
두 번째로, 계단식 삭제로 하위 테이블을 추가하면 사례 1의 코드가 계속 작동합니다.
관계의 의미가 "일부"인 캐스케이드 만 넣을 것입니다. 그렇지 않으면 다음과 같은 작업을 수행 할 때 일부 바보가 데이터베이스의 절반을 삭제합니다.
DELETE FROM CURRENCY WHERE CurrencyCode = 'USD'
다른 버전의 여러 모듈이있는 시스템에서 작업하는 경우 계단식 삭제 항목이 PK 홀더의 일부이거나 소유 된 경우 매우 유용 할 수 있습니다. 그렇지 않으면 모든 모듈이 PK 소유자를 삭제하기 전에 종속 항목을 정리하기 위해 즉시 패치가 필요하거나 외래 키 관계가 완전히 생략되어 정리가 올바르게 수행되지 않으면 시스템에 많은 쓰레기가 남을 수 있습니다.
계단식 삭제가 꽤 오랫동안 권장되지 않은 후 이미 존재하는 두 테이블 사이의 새 교차 테이블에 대한 계단식 삭제 (삭제 교차 만)를 소개했습니다. 데이터가 손실되는 경우에도 그렇게 나쁘지 않습니다.
그러나 열거 형과 같은 목록 테이블에서는 나쁜 점이 있습니다. 누군가가 테이블 "색상"에서 항목 13-노란색을 삭제하면 데이터베이스의 모든 노란색 항목이 삭제됩니다. 또한, 이들은 모두 삭제-삽입-전체 방식으로 업데이트되어 참조 무결성이 완전히 생략됩니다. 물론 그것은 틀렸지 만, 진정한 참조 무결성의 도입이 예기치 않은 부작용의 위험에 처해있는 상태에서 수년 동안 실행되었던 복잡한 소프트웨어를 어떻게 변화시킬 것입니까?
또 다른 문제는 기본 외래 키 값이 기본 키가 삭제 된 후에도 유지되어야하는 경우입니다. 원래 FK에 대해 삭제 표시 열과 ON DELETE SET NULL 옵션을 만들 수 있지만 중복 키 (PK 삭제 후 제외) 키 값을 유지하려면 트리거 또는 특정 코드가 다시 필요합니다.
계단식 삭제는 물리적 데이터베이스에서 논리적 슈퍼 유형 및 하위 유형 엔터티를 구현할 때 매우 유용합니다.
별도의 수퍼 유형 및 하위 유형 테이블을 사용하여 수퍼 유형 / 하위 유형을 물리적으로 구현하는 경우 (모든 하위 유형 속성을 단일 물리적 수퍼 유형 테이블로 롤업하는 것과 대조적으로) 일대일 이러한 테이블과 문제 간의 관계는 기본 키를이 테이블간에 100 % 동기화하는 방법이됩니다.
계단식 삭제는 다음과 같은 경우에 매우 유용한 도구입니다.
1) 수퍼 유형 레코드를 삭제하면 해당 단일 하위 유형 레코드도 삭제해야합니다.
2) 하위 유형 레코드를 삭제하면 수퍼 유형 레코드도 삭제해야합니다. 이는 하위 유형 테이블에 "중재하지 않은"삭제 트리거를 구현하여 해당 상위 유형 레코드를 이동하고 삭제하는 방식으로 하위 유형 레코드를 삭제합니다.
이러한 방식으로 계단식 삭제를 사용하면 수퍼 유형 레코드를 먼저 삭제하는지 또는 하위 유형 레코드를 먼저 삭제하는지에 관계없이 고아 슈퍼 유형 또는 하위 유형 레코드가 존재하지 않습니다.
sql-server
태그 를 제거하면 커뮤니티에 더 유용합니다 .