SQL Server에서 Cascading을 언제 사용해야하는 이유는 무엇입니까?
SQL Server에서 외래 키를 설정할 때 어떤 상황에서 삭제 또는 업데이트시 계단식으로 연결해야하며 그 이유는 무엇입니까?
이것은 아마도 다른 데이터베이스에도 적용됩니다.
나는 각 시나리오의 구체적 예를 위해 무엇보다도 가장 바람직하게 그것을 사용하는 사람으로부터 찾고 있습니다.
지금까지 본 내용 요약 :
- 어떤 사람들은 계단식을 전혀 좋아하지 않습니다.
캐스케이드 삭제
- Cascade Delete는 관계의 의미론이 독점적 인 "설명의 일부"를 포함 할 수있을 때 의미가 있습니다 . 예를 들어, OrderLine 레코드는 상위 주문의 일부이며 OrderLine은 여러 주문간에 공유되지 않습니다. 주문이 사라 졌다면, 주문 라인도 주문해야하며, 주문이없는 라인은 문제가됩니다.
- Cascade Delete의 일반적인 예는 SomeObject 및 SomeObjectItems입니다. 여기서 해당 주 레코드가 없으면 항목 레코드가 존재하지 않습니다.
- 기록을 보존하거나 삭제 된 비트 열만 1 / true로 설정 한 "소프트 / 논리 삭제"를 사용하는 경우 연속 삭제를 사용 하지 않아야 합니다.
캐스케이드 업데이트
- 계단식 업데이트는 테이블에서 서로 게이트 키 (ID / 자동 증가 열)가 아닌 실제 키를 사용하는 경우에 적합합니다.
- Cascade Update의 일반적인 예는 사용자 이름과 같이 변경 가능한 외래 키가있는 경우입니다.
- ID / 자동 증가 열인 키와 함께 계단식 업데이트를 사용 해서는 안됩니다 .
- 캐스케이드 업데이트는 고유 제한 조건과 함께 사용하는 것이 가장 좋습니다.
계단식 사용시기
- 작업을 캐스케이드하기 전에 사용자로부터 다시 강력한 확인을 받고 싶을 수도 있지만 이는 응용 프로그램에 따라 다릅니다.
- 외래 키를 잘못 설정하면 계단식 배열로 인해 문제가 발생할 수 있습니다. 그러나 그렇게하면 괜찮을 것입니다.
- 계단식을 이해하기 전에 계단식을 사용하는 것이 현명하지 않습니다. 그러나이 기능은 유용한 기능이므로 시간을내어 이해해야합니다.
외래 키는 데이터베이스의 참조 무결성을 보장하는 가장 좋은 방법입니다. 마술 때문에 캐스케이드를 피하는 것은 컴파일러의 모든 마술을 믿지 않기 때문에 모든 것을 어셈블리에 쓰는 것과 같습니다.
나쁜 것은 외래 키를 뒤로 만드는 것과 같이 외래 키를 잘못 사용한다는 것입니다.
Juan Manuel의 예제는 표준 예제입니다. 코드를 사용하면 데이터베이스에 가짜 DocumentItems가 남을 가능성이 더 높습니다.
계단식 업데이트는 예를 들어 사용자 테이블의 기본 키가 이름, 성 조합과 같이 변경할 수있는 것으로 데이터를 참조 할 때 유용합니다. 그런 다음 해당 조합의 변경 사항이 참조되는 곳으로 전파되기를 원합니다.
@Aidan, 당신이 말하는 그 명확성은 비용이 많이 들지 않습니다 . 데이터베이스에 가짜 데이터를 남길 수 있습니다 . 나에게는 보통 DB에 익숙하지 않으며 DB를 사용하기 전에 어떤 FK가 있는지 파악할 수 없기 때문에 그러한 두려움이 생깁니다. 개체가 개념적으로 관련되지 않았거나 역사를 보존 해야하는 곳에서 캐스케이드를 계속 사용하거나 연속적으로 잘못 사용합니다.
계단식 삭제를 사용하지 않습니다.
데이터베이스에서 무언가를 제거하려면 원하는 것을 데이터베이스에 명시 적으로 말하고 싶습니다.
물론 이들은 데이터베이스에서 사용할 수있는 함수이며 사용 가능한 경우가있을 수 있습니다. 예를 들어 'order'테이블과 'orderItem'테이블이있는 경우 주문.
나는 '매직'이 아닌 코드 (또는 저장 프로 시저)에서 수행하는 명확성을 좋아합니다.
같은 이유로 나는 트리거 팬도 아닙니다.
주의 할 점은 '주문'을 삭제하면 계단식 삭제에서 'orderItem'이 50 개를 제거하더라도 '1 행 영향'보고서가 다시 표시됩니다.
계단식 삭제로 많은 작업을 수행합니다.
데이터베이스에 대해 작업하는 사람이 원치 않는 데이터를 남기지 않을 수 있다는 것을 아는 것이 좋습니다. 종속성이 커지면 Management Studio의 다이어그램에서 제약 조건을 변경하기 만하면 sp 또는 데이터 액세스를 조정할 필요가 없습니다.
즉, 계단식 삭제와 순환 참조에는 1 가지 문제가 있습니다. 이는 계단식 삭제가없는 데이터베이스 부분으로 이어지는 경우가 많습니다.
많은 데이터베이스 작업을 수행하고 계단식 삭제가 유용한 경우는 거의 없습니다. 내가 효과적으로 사용한 것은 야간 작업에 의해 업데이트되는보고 데이터베이스에 있습니다. 마지막 가져 오기 이후에 변경된 최상위 레코드를 삭제 한 다음 수정 된 레코드 및 관련 레코드를 다시 가져 와서 변경된 데이터를 올바르게 가져옵니다. 데이터베이스의 맨 아래에서 맨 위까지 보이는 많은 복잡한 삭제를 작성하지 않아도됩니다.
캐스케이드 삭제는 데이터를 삭제하기 때문에 트리거만큼 나쁘지 않다고 생각하지 않습니다. 트리거에는 모든 종류의 불쾌한 물건이 포함될 수 있습니다.
일반적으로 실제 삭제를 피하고 논리적 삭제 (즉, isDeleted라는 비트 열이 true로 설정 됨)를 대신 사용하십시오.
예를 들어 엔터티 간 종속성이있는 경우를 예로들 수 있습니다. 예 : Document-> DocumentItems (Document를 삭제할 때 DocumentItems는 존재할 이유가 없습니다)
참조 PK 레코드가 제거 된 경우 FK가있는 레코드를 제거하려는 경우 계단식 삭제를 사용하십시오. 다시 말해, 참조 레코드없이 레코드가 의미가없는 경우입니다.
캐스케이드 삭제는 null 예외를 발생시키지 않고 기본적으로 죽은 참조가 제거되도록하는 데 유용합니다.
캐스케이드 삭제시 :
하위 테이블의 행을 삭제 하려는 경우 해당 테이블이 상위 테이블에서 삭제 된 경우 .
경우 삭제 캐스케이드에 다음 사용되지 않는 오류가 위해 발생합니다 참조 무결성 .
캐스케이드 ON시 :
기본 키의 변경 사항 을 외래 키로 업데이트 하려는 경우
과거의 나쁜 경험으로 인해 "On Delete Cascade"(및 기타) 사용을 금지하는 DBA 및 / 또는 "회사 정책"에 대해 들었습니다. 어떤 경우에는 한 남자가 서로를 부르는 세 가지 방아쇠를 썼습니다. 하나의 idjit의 조치로 인해 복구 3 일 동안 트리거가 완전히 금지되었습니다.
물론 일부 하위 데이터를 보존해야하는 경우와 같이 "삭제시 계단식"대신 트리거가 필요합니다. 그러나 다른 경우에는 On Delete 캐스케이드 방법을 사용하는 것이 완벽하게 유효합니다. "삭제시 계단식"의 주요 장점은 모든 하위 항목을 캡처한다는 것입니다. 사용자 지정 작성 트리거 / 저장 프로 시저가 올바르게 코딩되지 않으면 그렇지 않을 수 있습니다.
I believe the Developer should be allowed to make the decision based upon what the development is and what the spec says. A carpet ban based on a bad experience should not be the criteria; the "Never use" thought process is draconian at best. A judgement call needs to be made each and every time, and changes made as the business model changes.
Isn't this what development is all about?
One reason to put in a cascade delete (rather than doing it in the code) is to improve performance.
Case 1: With a cascade delete
DELETE FROM table WHERE SomeDate < 7 years ago;
Case 2: Without a cascade delete
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
Secondly, when you add in an extra child table with a cascade delete, the code in Case 1 keeps working.
I would only put in a cascade where the semantics of the relationship is "part of". Otherwise some idiot will delete half of your database when you do:
DELETE FROM CURRENCY WHERE CurrencyCode = 'USD'
I try to avoid deletes or updates that I didn't explicitly request in SQL server.
Either through cascading or through the use of triggers. They tend to bite you in the ass some time down the line, either when trying to track down a bug or when diagnosing performance problems.
Where I would use them is in guaranteeing consistency for not very much effort. To get the same effect you would have to use stored procedures.
I, like everyone else here, find that cascade deletes are really only marginally helpful (it's really not that much work to delete referenced data in other tables -- if there are lot of tables, you simply automate this with a script) but really annoying when someone accidentally cascade deletes some important data that is difficult to restore.
The only case where I'd use is if the data in the table table is highly controlled (e.g., limited permissions) and only updated or deleted from through a controlled process (like a software update) that has been verified.
A deletion or update to S that removes a foreign-key value found in some tuples of R can be handled in one of three ways:
- Rejection
- Propagation
- nullification.
Propagation is referred to as cascading.
There are two cases:
‣ If a tuple in S was deleted, delete the R tuples that referred to it.
‣ If a tuple in S was updated, update the value in the R tuples that refer to it.
If you're working on a system with many different modules in different versions, it can be very helpful, if the cascade deleted items are part of / owned by the PK holder. Else, all modules would require immediate patches to clean up their dependent items before deleting the PK owner, or the foreign key relation would be omitted completely, possibly leaving tons of garbage in the system if cleanup is not performed correctly.
I just introduced cascade delete for a new intersection table between two already existing tables (the intersection to delete only), after cascade delete had been discouraged from for quite some time. It's also not too bad if data gets lost.
It is, however, a bad thing on enum-like list tables: somebody deletes entry 13 - yellow from table "colors", and all yellow items in the database get deleted. Also, these sometimes get updated in a delete-all-insert-all manner, leading to referential integrity totally omitted. Of course it's wrong, but how will you change a complex software which has been running for many years, with introduction of true referential integrity being at risk of unexpected side effects?
Another problem is when original foreign key values shall be kept even after the primary key has been deleted. One can create a tombstone column and an ON DELETE SET NULL option for the original FK, but this again requires triggers or specific code to maintain the redundant (except after PK deletion) key value.
Cascade deletes are extremely useful when implementing logical super-type and sub-type entities in a physical database.
When separate super-type and sub-type tables are are used to physically implement super-types/sub-types (as opposed to rolling up all sub-type attributes into a single physical super-type table), there is a one-to-one relationship between these tables and the issue then becomes how to keep the primary keys 100% in sync between these tables.
Cascade deletes can be a very useful tool to:
1) Make sure that deleting a super-type record also deletes the corresponding single sub-type record.
2) Make sure that any delete of a sub-type record also deletes the super-type record. This is achieved by implementing an "instead-of" delete trigger on the sub-type table that goes and deletes the corresponding super-type record, which, in turn, cascade deletes the sub-type record.
Using cascade deletes in this manner ensures that no orphan super-type or sub-type records ever exist, regardless of whether you delete the super-type record first or the sub-type record first.
참고URL : https://stackoverflow.com/questions/59297/when-why-to-use-cascading-in-sql-server
'development' 카테고리의 다른 글
서버에서 데이터를 얻는 권장 방법 (0) | 2020.06.16 |
---|---|
ReactJS를 사용하여 입력 필드의 값을 얻는 방법은 무엇입니까? (0) | 2020.06.16 |
열거 형 정의에서 물결표 (~)는 무엇입니까? (0) | 2020.06.16 |
rabbitmq 버전 확인 (0) | 2020.06.16 |
PHP 세션 수정 / 하이재킹 (0) | 2020.06.16 |