추가 테이블 또는 비특정 외래 키?
-
09-06-2019 - |
문제
시스템에는 여러 유형의 개체가 있으며 각 개체는 데이터베이스에 자체 테이블을 가지고 있습니다.사용자는 이들 중 어떤 것에도 댓글을 달 수 있어야 합니다.댓글 테이블을 어떻게 디자인하시겠습니까?몇 가지 옵션을 생각해 볼 수 있습니다.
- 각 객체 유형(ObjectAID, ObjectBID 등)에 대한 FK 열이 있는 하나의 설명 테이블
- 각 객체 유형(ObjectAComments, ObjectBComments 등)에 대해 하나씩 여러 주석 테이블
- 유형("ObjectA")을 나타내는 다른 열이 있는 하나의 일반 FK(ParentObjectID)
당신은 어느 것을 선택하시겠습니까?제가 생각하지 못하는 더 좋은 방법이 있나요?
해결책
@palmsey
꽤 많지만, 내가 가장 자주 본 패턴의 변형은 제거됩니다. ObjectAID
외. ParentID
PK와 FK가 모두 됩니다. Parents
.그러면 다음과 같은 결과가 나옵니다.
Parents
ParentID
ObjectA
ParentID
(FK 및 PK)ColumnFromA NOT NULL
ObjectB
ParentID
(FK 및 PK)ColumnFromB NOT NULL
Comments
동일하게 유지됩니다.그런 다음 실수로 ID 생성을 제한하면 됩니다. ObjectA
행과 ObjectB
둘 다 동일한 것을 가리키는 행 Parents
열;가장 쉬운 방법은 사용 중인 것과 동일한 시퀀스(또는 무엇이든)를 사용하는 것입니다. Parents
~을 위한 ObjectA
그리고 ObjectB
.
또한 다음과 같은 스키마가 많이 표시됩니다.
Parents
ID
SubclassDiscriminator
ColumnFromA (nullable)
ColumnFromB (nullable)
그리고 Comments
변함없이 유지될 것입니다.그러나 이제 트리거를 작성하거나 다른 계층에서 수행하지 않고는 모든 비즈니스 제약 조건(하위 클래스의 속성은 모두 Null 가능)을 적용할 수 없습니다.
다른 팁
주석 가능한(더 좋은 단어가 없음) 테이블이 표준 상속 모델링 패턴 중 하나를 따르도록 스키마를 설계하는 것이 가능합니까?그렇다면 주석 테이블의 FK가 공통 상위 테이블을 가리키도록 할 수 있습니다.
@행크 게이
그래서 다음과 같습니다.
- 객체A
- 객체AID
- 부모ID
- 객체B
- 객체BID
- 부모ID
- 코멘트
- 댓글ID
- 부모ID
- 부모
- 부모ID
정확히 하나의 테이블을 가리키지 않는 일반 외래 키에 주의하세요.한 유형의 where 조건을 분할하고 여러 다른 테이블을 가리켜야 하는 경우 쿼리 성능이 크게 저하됩니다.유형이 몇 개만 있고 유형 수가 늘어나지 않는 경우 다른 테이블에 대해 별도의 null 허용 외래 키를 갖는 것이 좋지만 더 많은 유형이 있는 경우 다른 데이터 모델을 생각해내는 것이 좋습니다(예: @palmsey의 제안).
제가 좋아하는 것 중 하나는 일반/공통 테이블을 모든 개별 테이블에 연결하는 별도의 테이블을 갖는 것입니다.
따라서 Foo 및 Bar 개체와 Foo & Bar에 대한 주석의 경우 다음과 같습니다.
- 푸
- 푸아이디(PK)
- 술집
- 바 ID(PK)
- 논평
- 댓글 ID(PK)
- 댓글 텍스트
- Foo댓글
- 푸아이디(PK FK)
- 댓글 ID(PK FK)
- 바댓글
- 바 ID(PK FK)
- 댓글 ID(PK FK)
이 구조는:
- 공통 Comments 테이블을 가질 수 있습니다.
- 테이블 상속 기능이 있는 DB가 필요하지 않습니다.
- 댓글 관련 정보로 Foo 및 Bar 테이블을 오염시키지 않습니다.
- 댓글을 첨부할 수 있습니다. 다수의 객체(원할 수 있음)
- 원하는 경우 Foo/Bar와 Comment의 교차점에 다른 속성을 추가할 수 있습니다.
- 여전히 표준과의 관계를 유지합니다(예:빠르고 간단하며 신뢰할 수 있는) 외래 키