데이터베이스 설계 : 동일한 테이블에 대한 일대 다 관계


20

나는 Chequing_Account 테이블 (예산, iban 번호 및 계정의 다른 세부 정보가 포함되어 있음)이 0, 1 또는 많은 chequing 계정을 가질 수있는 두 개의 다른 테이블 Person 및 Corporation과 관련되어야하는 상황을 모델링해야합니다.

다시 말해서 나는 같은 테이블과 두 개의 일대 다 관계가 있습니다.

정규화 요구 사항을 존중하는이 문제에 대한 해결책을 듣고 싶습니다. 내가 들었던 대부분의 솔루션은 다음과 같습니다.

1) Person과 Corporation이 속한 공통 엔티티를 찾고이 테이블과 Chequing_Account 테이블 사이에 링크 테이블을 작성하십시오.이 경우에는 불가능하며 일반적인 문제는 해결하고 싶지만이 특정 인스턴스는 아닙니다.

2) 두 엔티티를 Chequing 계정과 연관시키는 PersonToChequingAccount 및 CorporationToChequingAccount 링크 테이블을 두 개 작성하십시오. 그러나 나는 두 사람이 같은 chequing 계정을 갖기를 원하지 않으며 자연인과 회사가 chequing 계정을 공유하기를 원하지 않습니다! 이 이미지를보십시오

http://i41.tinypic.com/35i6kbk.png

3) 회사 및 자연인을 가리키는 Chequing Account에 두 개의 외래 키를 작성하십시오. 그러나 개인과 회사가 많은 Chequing 계정을 가질 수 있도록 강요하지만 각 ChequingAccount 행마다 두 관계가 모두 일치하지 않도록 수동으로 확인해야합니다 체킹 계정이 법인 또는 자연인이기 때문에 법인 및 자연인. 이 이미지를보십시오

http://i40.tinypic.com/1rpv9z.png

이 문제에 대한 다른 깨끗한 해결책이 있습니까?


당신은 예에 대한 문제에 대해 생각 해본 적이 OwnerTypeIDChecquingAccount로, 테이블 1=Corporation2=NaturalPerson? 그런 식으로 테이블 OwnerID에 하나만 있으면 ChecquingAccount,와 함께 색인을 생성 할 수 있습니다 OwnerTypeID.
RoKa

나는 그것이 법인인지 자연인인지 알 필요가있을뿐만 아니라 각각의 ID를 알아야하기 때문에, 1 또는 2의 값뿐만 아니라 ID 번호도 필요합니다! 솔루션 3은 내가 찾은 것입니다. 회사 또는 자연인에게 ID가있는 두 개의 열이 있습니다.
dendini

2
예, 솔루션은 유효한 옵션입니다. 대부분의 DBMS에서는 체크 제약 조건으로 두 FK 중 하나만 "활성"상태로 둘 수 있습니다. CHECK (CorporationID IS NOT NULL AND NaturalPersonID IS NULL OR CorporationID IS NULL AND NaturalPersonID IS NOT NULL)솔루션 1을 선호하지만 그저 나뿐입니다. 훨씬 "더 깨끗하다".
ypercubeᵀᴹ

예, 이해합니다. 그러나 ChecquingAccount테이블에 OwnerTypeID=1OwnerID=123의 유형을 나타내는 레코드를 가질 수 있으므로 테이블의 CorporationID 123를 가질 수 있습니다 Corporation. OwnerTypeID는 어떤 테이블을 알려주고 OwnerID는 그 테이블의 ID를 알려줍니다.
로카

1
옵션 # 1은 어떻게 불가능합니까? "기업"이라는 단어는 기본적으로 "법적으로 사람인 사업"을 의미합니다. 그것을 Customers테이블 이라고 부릅니다 .
모든 거래의 존

답변:


15

관계형 데이터베이스는이 상황을 완벽하게 처리하도록 구축되지 않았습니다. 가장 중요한 것이 무엇인지 결정한 다음 절충해야합니다. 몇 가지 목표가 있습니다.

  • 세 번째 정규형 유지
  • 참조 무결성 유지
  • 각 계정이 회사 또는 자연인에게 속해야한다는 제약 조건을 유지하십시오.
  • 간단하고 직접 데이터를 검색 할 수있는 기능 유지

문제는 이러한 목표 중 일부가 서로 경쟁한다는 것입니다.

하위 입력 솔루션
회사와 개인을 모두 포함하는 수퍼 유형을 만드는 하위 입력 솔루션을 선택할 수 있습니다. 이 수퍼 타입은 아마도 서브 타입의 자연 키의 복합 키와 파티셔닝 속성 (예 :)을 가질 것입니다 customer_type. 이것은 정규화가 진행되는 한 괜찮으며 기업과 개인이 상호 배타적이라는 제약뿐만 아니라 참조 무결성을 강화할 수 있습니다. 문제는 항상 데이터를 검색하기가 더 어렵다는 것입니다.customer_type 계정을 계정 소유자에게 가입시킬 때 입니다. 이것은 아마도 UNION쿼리에서 많은 반복 SQL을 사용 하고 있음을 의미 합니다.

두 개의 외래 키 솔루션
계정 테이블에 두 개의 외래 키를 하나는 회사마다, 다른 하나는 사람으로 유지하는 솔루션을 선택할 수 있습니다. 이 솔루션을 사용하면 참조 무결성, 정규화 및 상호 독점 성을 유지할 수 있습니다. 또한 하위 입력 솔루션과 동일한 데이터 검색 단점이 있습니다. 실제로이 솔루션은 결합 로직 "수퍼"를 분기하는 문제를 제외하고는 하위 입력 솔루션과 같습니다.

그럼에도 불구하고 많은 데이터 모델러는 상호 독점 제약 조건이 적용되는 방식 때문에이 솔루션을 하위 입력 솔루션보다 열등한 것으로 간주합니다. 하위 입력 솔루션에서는 키를 사용하여 상호 독점 성을 적용합니다. 두 개의 외래 키 솔루션에서CHECK 제약 조건 . 수표 제한에 대한 부당한 편견이있는 사람들을 알고 있습니다. 이 사람들은 제약 조건을 키로 유지하는 솔루션을 선호합니다.

"비정규 화 된"분할 속성 솔루션
chequing 계정 테이블에 단일 외래 키 열을 유지하고 다른 열을 사용하여 외래 키 열을 해석하는 방법을 알려주는 다른 옵션이 있습니다 (RoKa 'sOwnerTypeID기둥). 이렇게하면 분할 특성을 자식 테이블로 비정규 화하여 하위 입력 솔루션에서 수퍼 유형 테이블이 제거됩니다. (파티셔닝 속성은 기본 키의 일부이기 때문에 공식 정의에 따라 엄격하게 "비정규 화"가 아닙니다.)이 솔루션은 거의 동일한 작업을 수행하기 위해 추가 테이블을 사용하지 않기 때문에 매우 단순 해 보입니다. 외래 키 열 수를 1로 줄입니다. 이 솔루션의 문제점은 검색 로직의 분기를 피하지 않으며 더 나아가 선언적 참조 무결성 을 유지할 수 없다는 것 입니다. SQL 데이터베이스에는 여러 부모 테이블 중 하나에 대한 단일 외래 키 열을 관리 할 수있는 기능이 없습니다.

공유 기본 키 도메인 솔루션
사람들이 때때로이 문제를 처리하는 한 가지 방법은 단일 ID 풀을 사용하여 특정 하위 유형에 속하는 것이 든 주어진 ID에 대해 혼동되지 않도록하는 것입니다. 이것은 기업과 자연인 모두에게 동일한 은행 계좌 번호를 발행하지 않기 때문에 아마도 은행 시나리오에서 자연스럽게 작동 할 것입니다. 이는 파티셔닝 속성이 필요 없다는 장점이 있습니다. 수퍼 유형 테이블 유무에 관계없이이를 수행 할 수 있습니다. 수퍼 유형 테이블을 사용하면 선언적 제한 조건을 사용하여 고유성을 강제 할 수 있습니다. 그렇지 않으면 절차 적으로 시행해야합니다. 이 솔루션은 정규화되었지만 수퍼 유형 테이블을 유지하지 않으면 선언적 참조 무결성을 유지할 수 없습니다. 복잡한 검색 논리를 피하기 위해 여전히 아무것도하지 않습니다.

따라서 데이터 검색을 단순하게 유지하면서 모든 규칙을 따르는 깔끔한 디자인이 실제로 불가능하다는 것을 알 수 있습니다. 트레이드 오프 위치를 결정해야합니다.


내 솔루션 # 2는 네 그룹 중 어느 그룹에 속합니까? "비정규 화 된 파티셔닝 속성 솔루션"은 분명하지 않습니다.
dendini

@dendini-솔루션 번호 2는 내가 설명한 솔루션과 맞지 않습니다. 한 법인에 속한 계정의 요구 사항에 맞지 않기 때문입니다. 중간 테이블의 기본 키를 정의한 방식은 다 대다 교차점입니다. 기본 키가 방금 corporation_idperson_id당신은 기본적으로 사람들이 여러 계정을하지를 잡을 수 있도록, 슈퍼 타입의 테이블을 두 개로 분할했을 것이다 및 외래 키가 반전 된 것을 제외하고는 서브 타이핑 솔루션을 것입니다. 이런 종류의 목적은 패배합니다.
Joel Brown

좋은 설명입니다. @JoelBrown, 쿼리와 관련하여 "두 개의 외래 키"솔루션의 성능 영향은 무엇입니까? 또한 2 개 대신 6 개 이상의 외래 키가있을 수 있습니다.이 방법을 계속 추천 하시겠습니까?
아마데오 갈라도

1
@AmadeoGallardo 대답은 "그것은 달려있다"입니다. 키에 대한 쿼리는 항상 탐색이 효율적이지 않은 경우 최소한 인덱스 스캔을 기대할 수 있기 때문에 항상 매우 효율적입니다. 이는 빠른 작업입니다. 두 개의 외래 키 솔루션 에서 두 키를 모두 쿼리하면 문제가 발생합니다 . 여기서 쿼리 최적화 프로그램에 작업을 수행하도록 요청하고 있습니다. 기껏해야 하나의 키에 대해 쿼리 한 다음 다른 키에 대해 쿼리 한 다음 결과를 병합해야하기 때문에 쿼리 비용이 두 배로 늘어납니다.
Joel Brown

@JoelBrown 비정규 미래의 SQL 버전은 두 개의 열을 기반으로 복합 외부 키의 정의를 허용함으로써 이러한 접근을 허용해야 RefID하고RefTable 어디에 RefTable고정하는 것을 식별 ID 목표 테이블이다. 이 유형의 키에는 무결성을 강화하기 위해 10 개 이상의 연관 / 하위 유형 테이블을 유지 보수하는 데 많은 유스 케이스가 있습니다. 그런 경우에 나는 이것을 key직접 만들었다 .
djmj
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.