programing

SQL Server에서 Cascading을 사용해야 하는 이유 및 시기

css3 2023. 4. 10. 22:10

SQL Server에서 Cascading을 사용해야 하는 이유 및 시기

SQL Server에서 외부 키를 설정할 때 삭제 또는 업데이트 시 캐스케이드해야 하는 상황과 그 이유는 무엇입니까?

이는 다른 데이터베이스에도 적용될 수 있습니다.

저는 특히 각 시나리오의 구체적인 예를 찾고 있습니다.가능하다면, 그것들을 성공적으로 사용한 사람으로부터요.

지금까지 본 내용 요약:

  • 어떤 사람들은 캐스케이드를 전혀 좋아하지 않는다.

계단식 삭제

  • 캐스케이드 삭제는 관계의 의미론에서 배타적인 "일부" 설명을 포함할 수 있는 경우에 의미가 있을 수 있습니다.예를 들어 OrderLine 레코드는 상위 주문의 일부이며 OrderLine은 여러 주문 간에 공유되지 않습니다.주문이 사라지면 OrderLine도 사라지며 Order가 없는 행이 문제가 됩니다.
  • Cascade Delete의 표준 예는 SomeObject와 SomeObjectItems입니다.이 예에서는 대응하는 메인레코드 없이 아이템레코드가 존재하는 것은 의미가 없습니다.
  • 이력을 보존하는 경우 또는 삭제된 비트열을 1/true로만 설정하는 "소프트/논리 삭제"를 사용하는 경우에는 캐스케이드 삭제를 사용하지 마십시오.

캐스케이드 업데이트

  • 캐스케이드 업데이트는 테이블 전체에서 대리 키(ID/자동 증가 열)가 아닌 실제 키를 사용하는 경우에 적합합니다.
  • 캐스케이드 업데이트의 표준 예는 변경 가능한 사용자 이름과 같은 가변 가능한 외부 키가 있는 경우입니다.
  • Identity/autoincrement 컬럼인 키에는 Cascade Update를 사용하지 마십시오.
  • 캐스케이드 업데이트는 고유한 제약 조건과 함께 사용하는 것이 가장 좋습니다.

캐스케이딩을 사용하는 경우

  • 조작을 캐스케이드 하기 전에, 유저로부터 한층 더 강력한 확인을 받고 싶은 경우가 있습니다만, 사용하시는 애플리케이션에 따라 다릅니다.
  • 외부 키를 잘못 설정하면 캐스케이드로 인해 문제가 발생할 수 있습니다.하지만 제대로 하면 괜찮을 거예요.
  • 캐스케이딩을 완전히 이해하기 전에 사용하는 것은 현명하지 않습니다.단, 이것은 유용한 기능이기 때문에 시간을 들여 이해할 필요가 있습니다.

외부 키는 데이터베이스의 참조 무결성을 보장하는 가장 좋은 방법입니다.마법이 있기 때문에 계단식 구조를 피하는 것은 컴파일러의 마법을 믿지 않기 때문에 어셈블리의 모든 것을 쓰는 것과 같습니다.

나쁜 점은 예를 들어 외부 키를 거꾸로 작성하는 등 잘못된 사용입니다.

Juan Manuel의 예는 표준적인 예이며, 코드를 사용하면 가짜 문서를 남길 가능성이 더 높습니다.데이터베이스 내의 아이템이 당신을 괴롭힐 것입니다.

캐스케이드 업데이트는 예를 들어 변경이 가능한 데이터에 대한 참조가 있는 경우 사용자 테이블의 프라이머리 키가 이름과 성의 조합이라고 하면 편리합니다.그런 다음 해당 조합의 변경 내용을 참조하는 모든 위치에 전파해야 합니다.

@Aidan씨, 당신이 말하는 명확성은 비용이 많이 들고 가짜 데이터를 데이터베이스에 남길 가능성이 있습니다.이것은 결코 작지 않습니다.일반적으로 DB에 대한 지식이 부족하고, 이러한 두려움을 조장하는 DB와 함께 작업하기 전에 어떤 FK가 있는지 찾을 수 없다는 것입니다.개념적으로 관련되지 않은 엔티티 또는 이력 보존이 필요한 장소에서 캐스케이드를 계속 오용하는 것 중 하나입니다.

단계적 삭제는 사용하지 않습니다.

데이터베이스에서 무언가를 제거하려면 데이터베이스에 무엇을 꺼내야 하는지 명시적으로 알려야 합니다.

물론 데이터베이스에서 사용할 수 있는 기능이며, 예를 들어 '주문' 테이블과 '주문' 테이블이 있는 경우 사용할 수 있는 경우가 있습니다.Item' 테이블은 주문을 삭제할 때 항목을 지울 수 있습니다.

마법 같은 일이 일어나는 것보다 코드(또는 저장 프로시저)로 실행함으로써 얻을 수 있는 명확성이 마음에 듭니다.

같은 이유로 나도 트리거를 좋아하지 않는다.

주의할 점은 '주문'을 삭제한 경우 계단식 삭제로 50개의 '주문'이 제거되었더라도 '해당 1줄' 보고서가 반환된다는 것입니다.아이템의

계단식 삭제 작업을 많이 합니다.

데이터베이스에 대해 작업하는 사람이 원치 않는 데이터를 남기지 않을 수 있다는 것을 알게 되어 기쁩니다.의존관계가 증가하면 Management Studio의 다이어그램에 있는 제약조건을 변경하기만 하면 됩니다.또한 SP나 dataaces를 변경할 필요가 없습니다.

즉, 삭제 캐스케이드 및 순환 참조에 관한 문제가 1개 있습니다.이로 인해 데이터베이스의 일부가 단계적 삭제가 없는 경우가 많습니다.

데이터베이스 작업을 많이 하지만 캐스케이드 삭제는 거의 도움이 되지 않습니다.야간 작업에 의해 업데이트되는 보고서 데이터베이스에서 이러한 데이터를 효과적으로 사용한 적이 있습니다.마지막으로 Import한 이후 변경된 최상위 레코드를 삭제하고 수정된 레코드 및 관련 레코드를 다시 Import하여 변경된 데이터를 올바르게 Import합니다.이렇게 하면 데이터베이스의 맨 아래부터 맨 위까지 복잡한 삭제를 많이 작성할 필요가 없어집니다.

캐스케이드 삭제가 트리거만큼 나쁘다고는 생각하지 않습니다.데이터만 삭제하기 때문에 트리거에는 모든 종류의 불쾌한 것이 포함되어 있을 수 있습니다.

일반적으로 실제 삭제는 모두 피하고 논리적 삭제(즉,대신 isDeleted라는 이름의 비트 열이 true로 설정됩니다.

예를 들어 엔티티 간에 종속성이 있는 경우...즉, 문서 -> 문서항목(문서, 문서 삭제 시)아이템은 존재할 이유가 없습니다.)

캐스케이드 삭제 시:

부모 테이블에서 해당 행을 삭제한 경우 자녀 테이블의 행을 삭제할 경우.

on cascade delete를 사용하지 않으면 참조 무결성에 대한 오류가 발생합니다.

업데이트 캐스케이드:

기본 키의 변경을 외부 키로 업데이트하려는 경우

참조하고 있는 PK 레코드가 삭제되었을 경우, FK 를 가지는 레코드를 삭제하는 경우는, 캐스케이드 삭제를 사용합니다.즉, 참조 레코드가 없으면 레코드가 무의미합니다.

cascade delete는 null 예외를 발생시키지 않고 dead reference를 디폴트로 삭제하는데 도움이 됩니다.

과거에 단순히 좋지 않은 경험 때문에 "On Delete Cascade"(및 기타) 사용을 금지하는 DBA 및/또는 "회사 정책"에 대해 들어본 적이 있습니다.어떤 경우에는 한 남자가 세 개의 트리거를 썼고 결국 서로에게 전화를 걸었습니다.복구하는 데 3일이 걸렸는데, 이 모든 것이 하나의 idjit의 액션으로 인해 트리거가 완전히 금지되었습니다.

물론 일부 하위 데이터를 보존해야 하는 경우처럼 "삭제 단계" 대신 트리거가 필요할 수 있습니다.그러나 다른 경우에는 On Delete 캐스케이드 방식을 사용하는 것이 완벽하게 유효합니다."On Delete cascade"의 주요 장점은 모든 하위 항목을 캡처한다는 것입니다. 올바르게 코딩되지 않으면 사용자 정의 트리거/저장 절차가 캡처되지 않을 수 있습니다.

개발자는 개발 내용과 사양에 따라 결정을 내릴 수 있어야 한다고 생각합니다.나쁜 경험에 근거한 카펫 금지가 기준이 되어서는 안 된다; "절대 사용하지 않는" 사고 과정은 기껏해야 엄격하다.판단 호출은 매번 이루어져야 하며 비즈니스 모델의 변화에 따라 변경되어야 합니다.

개발이란 이런 거 아닌가요?

(코드로 하는 것이 아니라) 계단식 삭제를 하는 이유 중 하나는 성능 향상입니다.

케이스 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'

SQL 서버에서 명시적으로 요청하지 않은 삭제나 업데이트를 피하려고 합니다.

캐스케이드 또는 트리거 사용 중 하나입니다.버그를 추적하거나 퍼포먼스 문제를 진단할 때 그들은 항상 당신을 괴롭히는 경향이 있습니다.

내가 그것들을 사용하는 곳은 별로 노력하지 않고 일관성을 보장하는 것이다.동일한 효과를 얻으려면 저장 프로시저를 사용해야 합니다.

여기 있는 다른 모든 사람들과 마찬가지로 캐스케이드 삭제는 매우 유용하지만(다른 테이블의 참조 데이터를 삭제하는 작업은 그다지 많지 않습니다.테이블이 많으면 스크립트를 사용하여 이 작업을 자동화합니다) 누군가 실수로 복원하기 어려운 중요한 데이터를 삭제했을 때 매우 짜증납니다.

테이블 내의 데이터가 고도로 제어되고(예: 제한된 권한) 검증된 제어된 프로세스(소프트웨어 업데이트 등)를 통해서만 업데이트 또는 삭제되는 경우만 사용할 수 있습니다.

R의 일부 튜플에 있는 외부 키 값을 삭제하는S로의 삭제 또는 업데이트는 다음 3가지 방법 중 하나로 처리할 수 있습니다.

  1. 거부.
  2. 전파
  3. 무효화

전파는 캐스케이드라고 불립니다.

두 가지 경우가 있습니다.

② S의 Tuple이 삭제되었을 경우, 해당 Tuple을 참조한 R Tuple을 삭제한다.

② S의 tuple이 갱신되었을 경우, 그것을 참조하는 R tuple의 값을 갱신한다.

다른 버전의 여러 모듈이 있는 시스템에서 작업하는 경우 삭제된 항목이 PK 홀더의 일부이거나 PK 홀더에 의해 소유되는 경우 매우 유용합니다.그렇지 않으면 모든 모듈에서 PK 소유자를 삭제하기 전에 종속 항목을 즉시 정리하는 패치가 필요합니다. 그렇지 않으면 외부 키 관계가 완전히 생략되어 정리가 제대로 수행되지 않으면 시스템에 엄청난 양의 가비지가 발생할 수 있습니다.

오랫동안 캐스케이드 삭제가 권장되지 않았던 기존 2개의 테이블(삭제하는 교차로만) 사이에 새로운 교차로 테이블에 대해 캐스케이드 삭제를 도입했습니다.데이터가 손실되어도 나쁘지 않습니다.

그러나 열거형 목록 테이블에서는 단점이 있습니다.누군가가 테이블 "colors"에서 13 - 노란색 항목을 삭제하면 데이터베이스 내의 노란색 항목이 모두 삭제됩니다.또한 이러한 정보는 delete-all-insert-all 방식으로 업데이트되어 참조 무결성이 완전히 누락될 수 있습니다.물론 틀렸습니다만, 몇 년 동안 실행되어 온 복잡한 소프트웨어를 어떻게 바꾸시겠습니까?참된 참조 무결성의 도입은 예기치 않은 부작용의 위험에 처해 있습니다.

또 다른 문제는 기본 키가 삭제된 후에도 원래의 외부 키 값을 유지해야 하는 경우이다.원래 FK에 대해 묘비열과 ON DELETE SET NULL 옵션을 만들 수 있지만, 이 경우에도 중복(PK 삭제 후 제외) 키 값을 유지하려면 트리거 또는 특정 코드가 필요합니다.

캐스케이드 삭제는 물리 데이터베이스에 논리적인 슈퍼타입 엔티티 및 서브타입 엔티티를 실장하는 경우에 매우 편리합니다.

(모든 서브타입 Atribut을 하나의 물리 슈퍼타입 테이블로 롤업하는 것이 아니라) 슈퍼타입/서브타입 테이블을 물리적으로 구현하기 위해 별도의 슈퍼타입 테이블과 서브타입 테이블을 사용하는 경우 이들 테이블 사이에는 1대1의 관계가 존재하며 문제는 이들 테이블 간에 프라이머리 키를 100% 동기화 상태로 유지하는 방법입니다.

캐스케이드 삭제는 다음 작업에 매우 유용한 도구입니다.

1) 슈퍼타입 레코드를 삭제한 경우 해당 단일 서브타입 레코드도 삭제해야 합니다.

2) 서브타입 레코드의 삭제 시 슈퍼타입 레코드의 삭제 여부를 확인한다.이는 서브타입 테이블에 "대신" 삭제 트리거를 구현함으로써 실현됩니다.이 트리거는 대응하는 슈퍼타입 레코드를 삭제하고, 그 슈퍼타입 레코드는 캐스케이드 방식으로 서브타입 레코드를 삭제합니다.

이 방법으로 캐스케이드 삭제를 사용하면 슈퍼타입 레코드를 먼저 삭제할지 서브타입 레코드를 먼저 삭제할지 여부에 관계없이 분리된 슈퍼타입 레코드와 서브타입 레코드는 존재하지 않습니다.

와는 구별하고 싶다.

  • 데이터 무결성
  • 비즈니스 로직/규칙

내 경험으로는 PK, FK 및 기타 제약조건을 사용하여 데이터베이스에서 최대한 무결성을 적용하는 것이 가장 좋습니다.

단, 비즈니스 규칙/논리 IMO는 일관성을 이유로 코드를 사용하여 구현되는 것이 가장 좋습니다(구글의 "커플링과 통합"은 자세한 내용을 참조).

캐스케이드 삭제/업데이트는 데이터 무결성 또는 비즈니스 규칙입니까?이것은 물론 논의될 수 있지만 나는 보통 논리/규칙이라고 말하고 싶다.예를 들어 비즈니스 규칙은 다음과 같습니다.Order모두 삭제되었습니다.OrderItems자동으로 삭제됩니다.단, 이 명령어를 삭제할 수 없는 경우도 있습니다.Order아직 가지고 있다면OrderItems따라서 이것은 비즈니스가 결정할 수 있습니다.이 규칙이 현재 어떻게 구현되고 있는지 어떻게 알 수 있습니까?모든 것이 코드로 되어 있는 경우는, 코드로 확인할 수 있습니다(높은 응집력).규칙이 코드로 구현되거나 데이터베이스에서 캐스케이드로 구현될 수 있는 경우 여러 곳을 조사해야 합니다(접속도가 낮음).

물론 비즈니스 규칙만 데이터베이스에 저장하고 트리거를 사용하는 경우 저장된 proc는 의미가 있습니다.

보통 저장된 proc 또는 트리거를 사용하기 전에 데이터베이스 벤더의 lock-in을 고려합니다.데이터를 저장하고 무결성을 적용하는 SQL 데이터베이스를 사용하면 IMO를 다른 벤더에 쉽게 이식할 수 있습니다.그래서 저는 보통 저장 프로시저나 트리거를 사용하지 않습니다.

언급URL : https://stackoverflow.com/questions/59297/when-why-to-use-cascading-in-sql-server