외국의 키 캐스케이드에 의존하는 것이 나쁜가요?
제가 참여하고 있는 프로젝트의 책임 개발자는 관련된 행을 삭제하기 위해 계단식에 의존하는 것은 나쁜 관행이라고 말합니다.
이것이 얼마나 나쁜지는 모르겠지만, 나는 그것이 나쁜지에 대한 당신의 생각을 알고 싶습니다.
저는 행 주기를 거의 삭제하지 않는다는 말로 이 글을 시작하겠습니다.일반적으로 보관하려는 대부분의 데이터입니다.삭제된 것으로 표시하면 사용자에게 표시되지 않습니다(즉, 삭제된 것으로 표시됨).물론 데이터에 따라 다르며 사용자가 카트를 비울 때 실제로 기록을 삭제하는 것(예: 장바구니 내용)도 다릅니다.
여기서의 문제는 실제로 삭제하고 싶지 않은 레코드를 의도치 않게 삭제할 수 있다는 것입니다.그러나 참조 무결성은 이를 방지해야 합니다.그래서 명시적인 경우 외에는 이에 반대하는 이유가 보이지 않습니다.
저는 당신이 최소한의 놀라움의 원칙을 따른다고 생각합니다.
계단식 삭제로 인해 예기치 않은 데이터 손실이 발생해서는 안 됩니다.삭제할 때 관련 레코드를 삭제해야 하고 사용자가 해당 레코드가 없어짐을 알아야 하는 경우 계단식 삭제를 사용해서는 안 됩니다.대신 사용자에게 관련 기록을 명시적으로 삭제하도록 요구하거나 알림을 제공해야 합니다.
반면, 테이블이 본질적으로 일시적이거나 상위 엔티티가 없어진 후에는 필요하지 않은 레코드를 포함하는 다른 테이블과 관련된 경우에는 계단식 삭제가 가능할 수 있습니다.
그렇기는 하지만, 저는 계단식 삭제에 의존하기 보다는 코드에 관련된 기록을 삭제함으로써 제 의도를 명시적으로 밝히는 것을 선호합니다.사실 저는 관련 기록을 암묵적으로 삭제하기 위해 계단식 삭제를 사용한 적이 없습니다.또한 클레투스가 설명한 대로 소프트 삭제를 많이 사용합니다.
저는 계단식 삭제를 사용하지 않습니다. 왜죠?왜냐하면 실수하기가 너무 쉽기 때문입니다.클라이언트 응용프로그램이 명시적으로 삭제하도록 요구하는 것이 훨씬 안전합니다(예: FK 참조 레코드 삭제 등 삭제 조건 충족).
실제로 기록을 삭제된 것으로 표시하거나 보관/기록 테이블로 이동하면 삭제 자체를 피할 수 있습니다.
삭제된 것으로 기록을 표시하는 경우에는 삭제된 것으로 표시된 데이터의 상대적인 비율에 따라 달라지므로,SELECTs는 '을(를) 필터링해야 합니다.isDeleted = false이 의 10% (RDB).MS에 따라 약)이 삭제된 것으로 표시된 경우에만 사용됩니다.
다음 두 가지 시나리오 중 어느 것을 원하십니까?
개발자가 당신에게 와서 "야, 이 삭제는 작동하지 않을 거야"라고 말합니다.두 분 다 그걸 조사해 보시고 그가 실수로 전체 테이블 내용을 삭제하려 했다는 걸 알게 되실 겁니다.둘 다 웃으시면서 하던 일로 돌아가세요.
개발자가 여러분을 찾아와서 "우리에게 백업이 있습니까?"라고 수줍게 묻습니다.
계단식 업데이트나 삭제를 사용하지 않는 또 다른 큰 이유가 있습니다. 바로 직렬화 가능한 잠금을 보유하고 있다는 것입니다.직렬화 가능한 잠금 상태를 유지하면 성능이 저하될 수 있습니다.
계단식 삭제를 피하는 또 다른 큰 이유는 성능 때문입니다.메인 테이블에서 10,000개의 레코드를 삭제해야 할 때까지 이 레코드들은 좋은 아이디어인 것 같습니다. 이 레코드들은 또한 어린이 테이블에 수백만 개의 레코드를 가지고 있습니다.이 삭제 내용의 크기를 고려할 때, 테이블을 몇 시간, 심지어 며칠 동안 완전히 잠글 가능성이 높습니다.왜 이런 위험을 감수하는 겁니까?한 개의 레코드 삭제에 대한 추가 삭제 설명문을 작성하는 데 10분의 시간을 단축할 수 있는 편의를 위해?
또한, 자식 기록이 있는 레코드를 삭제하려고 할 때 발생하는 오류는 종종 좋은 것입니다.이 레코드를 삭제할 경우 손실될 데이터가 있기 때문에 삭제하고 싶지 않다는 것을 알려줍니다.캐스케이드 삭제를 수행하면 이전에 주문을 받은 고객을 삭제한 경우 하위 레코드가 삭제되어 주문에 대한 정보가 손실됩니다.이런 종류의 일은 당신의 재무 기록을 완전히 엉망으로 만들 수 있습니다.
저도 마찬가지로 계단식 삭제는 나쁜 관행이라고 들었습니다.그래서 그걸 사용한 고객을 만나기 전까지는 사용하지 않았습니다.저는 제가 왜 그것들을 사용하지 않아야 하는지 정말 몰랐지만, 그것들이 모든 FK 기록들을 삭제하는 코드를 코드아웃할 필요가 없다는 점에서 매우 편리하다고 생각했습니다.
그래서 저는 그들이 왜 그렇게 "나쁜" 것인지 조사해보기로 결정했고 지금까지 제가 발견한 바로는 그들이 그들에 대해 아무런 문제가 없는 것 같습니다.사실 제가 지금까지 본 유일한 좋은 주장은 HLGLEM이 위에서 성능에 대해 언급한 것입니다.하지만 저는 보통 이 정도의 레코드를 삭제하지 않기 때문에 대부분의 경우에는 레코드를 사용해도 괜찮을 것 같습니다.저는 다른 사람들이 제가 모든 선택 사항을 고려했는지 확인하기 위해 그것을 사용하는 것에 반대할 수도 있는 다른 주장에 대해 듣고 싶습니다.
또한 ON DELETE CASCADE는 대부분의 상용 ETL 툴이 작동하는 방식인 binlog 복제를 사용하여 데이터 웨어하우스에서 데이터의 복사본을 유지하는 것을 어렵게 한다고 덧붙였습니다.각 테이블에서 명시적으로 삭제하면 전체 로그 기록이 유지되고 데이터 팀에서 훨씬 더 쉬워집니다.
저는 사실 여기서 대부분의 답변에 동의합니다. 하지만 모든 시나리오가 동일한 것은 아니며, 당면한 상황과 해당 결정의 엔트로피가 어떻게 되는지에 따라 달라집니다. 예를 들어:
다수의 엔티티와 여러 개 또는 여러 개의 관계를 맺고 있는 엔티티에 대한 삭제 명령이 있는 경우 해당 삭제 프로세스를 호출할 때마다 A가 해당 관계에 있는 각 관계형 피벗에서 해당하는 모든 FK를 삭제해야 합니다.
반면에 삭제 시 계단식을 통해 스키마의 일부로 한 번만 작성하면 해당 FK가 삭제되고 더 이상 필요 없는 관계에서 피벗을 정리할 수 있습니다. 엔티티 + 그 위에 많은 수의 관계가 있는 다른 엔티티에 대한 24개의 관계를 상상해 보십시오.설정과 편안함에 따라 달라질 수 있습니다.FYI의 경우에만 Illuminate 마이그레이션 스키마 파일에 다음과 같이 쓸 수 있습니다.
$table->dropForeign(['permission_id']);
$table->foreign('permission_id')
->references('id')
->on('permission')
->onDelete('cascade');
언급URL : https://stackoverflow.com/questions/2204792/is-it-bad-to-rely-on-foreign-key-cascading
'programing' 카테고리의 다른 글
| C# 세션 지우기 (0) | 2023.10.23 |
|---|---|
| C에서 선언 후 배열을 초기화할 수 있습니까? (0) | 2023.10.23 |
| XmlSerializer에서 Null 값 유형을 내보내지 않도록 억제 (0) | 2023.10.23 |
| 계층적 역할 기반 접근 제어 시스템 설계 방법 (0) | 2023.10.23 |
| iframe으로 Woocommerce 결제 게이트웨이를 구축하는 방법 (0) | 2023.10.18 |