문제

테이블 구조가 있지만 최선의 방법을 만드는 방법이 확실하지 않습니다.

기본적으로 tblSystemItems와 tblClientItems라는 두 개의 테이블이 있습니다.'항목'을 참조하는 열이 있는 세 번째 테이블이 있습니다.문제는 이 열이 시스템 항목이나 클라이언트 항목 중 하나를 참조해야 한다는 것입니다. 어느 항목인지는 중요하지 않습니다.시스템 항목에는 1..2^31 범위의 키가 있고 클라이언트 항목에는 -1..-2^31 범위의 키가 있으므로 충돌이 발생하지 않습니다.

항목을 쿼리할 때마다 두 테이블의 내용 간에 UNION ALL을 수행하는 뷰를 통해 쿼리를 수행합니다.

따라서 뷰는 항상 고유한 ID를 유지하면서 항상 두 테이블의 합집합이 되기 때문에 외래 키 참조를 뷰의 결과로 만드는 것이 가장 좋습니다.하지만 뷰를 참조할 수 없기 때문에 이 작업을 수행할 수 없습니다.

이제 외래 키만 삭제하면 모든 것이 정상입니다.그러나 나는 몇 가지 참조 확인 및 계단식 삭제/설정 null 기능을 갖고 싶습니다.트리거 외에 이를 수행할 수 있는 방법이 있습니까?

도움이 되었습니까?

해결책

늦은 답변에 대해 죄송합니다. 저는 주말염의 심각한 사례에 부딪 쳤습니다.

클라이언트와 시스템 테이블 모두에서 PKS를 포함하도록 세 번째 테이블을 사용하여 동기화를 지나치게 복잡하게 만들고 여전히 내 앱이 세 번째 테이블을 알아야한다는 점이 마음에 들지 않습니다.

발생한 또 다른 문제는 시스템이나 클라이언트와 같은 항목을 참조 해야하는 세 번째 테이블이 있다는 것입니다. 테이블을 분리한다는 것은 기본적으로 ClientItemID와 SystemItemID의 두 개의 열이 있어야한다는 것을 의미합니다.

나는 다른 해결책을 선택하게되었습니다. 전체 문제는 클라이언트 항목을 엉망으로 만들지 않고 충돌 등을 피하지 않고 새로운 시스템 항목을 쉽게 테이블에 동기화하는 것이 었습니다.

결국 단일 테이블, 항목 만 만들었습니다. 항목에는 "SystemItem"이라는 비트 열이 있습니다. 내 개발 / 시스템 데이터베이스에서 PK를 INT ID (1,1)로 받았습니다. 클라이언트 데이터베이스에서 테이블이 생성 된 후 ID 키는 (-1, -1)으로 변경됩니다. 즉, 클라이언트 항목은 음수로 들어가는 반면 시스템 항목은 긍정적 인 것으로 나타납니다.

동기화의 경우 기본적으로 (SystemItem = 1)로 무엇이든 무시하고 나머지는 Identity Insert를 사용하여 동기화합니다. 따라서 클라이언트 항목을 완전히 무시하고 충돌을 피하면서 동기화 할 수 있습니다. 또한 클라이언트와 시스템 항목을 모두 다루는 하나의 "항목"테이블 만 참조 할 수 있습니다. 명심해야 할 유일한 것은 표준 클러스터 키를 수정하여 클라이언트가 새 항목을 삽입 할 때 모든 종류의 페이지 구조 조정을 피하기 위해 내림차순입니다 (클라이언트 업데이트 대 시스템 업데이트는 99%/1%입니다).

다른 팁

항목을 참조하는 테이블에 대한 고유 ID (DB 생성 - 시퀀스, Autoinc 등)를 만들고 두 개의 추가 열을 생성 할 수 있습니다.tblsystemitemsfk 그리고 tblclientitemsfk) 시스템 항목과 클라이언트 항목을 각각 참조하는 경우 - 약간 데이터베이스는이 외국 키를 가질 수 있습니다. 무효.

ORM을 사용하는 경우 열 정보만으로 클라이언트 항목 및 시스템 항목을 쉽게 구별 할 수 있습니다 (이 방법으로 ID 중첩을 방지하기 위해 부정적인 식별자가 필요하지 않음).

Bakcground/Context가 조금 더 있으면 최적의 솔루션을 결정하는 것이 더 쉽습니다.

아마도 두 테이블의 모든 기본 키를 단순히 저장하는 tblItems라는 테이블이 필요할 것입니다.항목을 삽입하려면 항목이 tblSystemItems 테이블에 입력될 때 PK가 tblItems 테이블에 입력되는지 확인하기 위해 두 단계가 필요합니다.

세 번째 테이블에는 tblItems에 대한 FK가 있습니다.어떤 면에서는 tblItems가 다른 두 항목 테이블의 상위 항목입니다.항목을 쿼리하려면 tblItems, tblSystemItems 및 tblClientItems 사이에 JOIN을 생성해야 합니다.

[아래 설명 편집] tblSystemItems 및 tblClientItems가 자체 PK를 제어하는 ​​경우에도 허용할 수 있습니다.아마도 먼저 tblSystemItems에 삽입한 다음 tblItems에 삽입할 것입니다.당신이 Hibernate와 같은 도구를 사용하여 상속 구조를 구현할 때 당신은 이와 같은 결과를 얻게 됩니다.

pk itemid가있는 항목이라는 테이블과 itemtype = "system"또는 "client"라는 단일 열을 추가 한 다음 clientItems pk (clientItemId) 및 systemItems pk (systemItemId)도 items.itemid, (fks)가 있습니다. 이러한 관계는 0에서 하나의 관계입니다 (0-1)

그런 다음 항목을 참조하는 세 번째 테이블 에서이 추가 (항목) 테이블에 itemid를 참조하는 FK 제약 조건을 참조하십시오 ...

저장된 절차를 사용하여 인서트를 구현하는 경우, 항목을 삽입하는 저장된 Proc 만 있으면 먼저 항목 테이블에 새 레코드를 삽입 한 다음 해당 테이블의 자동 생성 된 PK 값을 사용하여 실제 데이터 레코드를 SystemItems 또는 어느 시스템에 삽입하십시오. 시스템이 항목 테이블 itemID 열에 삽입 된 자동 생성 (ID) 값을 사용하여 동일한 저장된 PROC 호출의 일부로 ClientItems (어디에 있는지).

이것을 "서브 클래싱"이라고합니다.

나는 당신의 테이블 디자인에 당황했습니다. 나는 그것이 옳다고 확신하지 못한다. 세 번째 테이블은 세부 정보를 제공 할 수 있다는 것을 알고 있지만 기본 키가 실제로 항목 테이블에 있고 외래 키는 시스템 및 클라이언트 항목 테이블의 키라고 생각하는 데 도움이 될 수 없습니다. 그런 다음 항목에서 시스템 및 클라이언트 항목 테이블로 오른쪽 외부 조인을 수행하면 모든 제약 조건이 잘 작동합니다.

사용중인 데이터베이스에서 비슷한 상황이 있습니다. 각 테이블에 EntityId를 호출하는 "후보 키"가 있습니다. 그런 다음 다른 테이블 중 하나 이상의 항목을 참조 해야하는 테이블이있는 경우 EntityId를 사용하여 해당 행을 참조합니다. 나는 모든 것을 교차 참조 할 수있는 엔티티 테이블이 있습니다 (EntityId는 엔티티 테이블의 주요 키이고 다른 모든 EntityId는 FKS입니다). 그러나 엔티티 테이블을 자주 사용하는 것은 아닙니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top