여러 테이블에 식별 시퀀스를 넣을 수있는 경우에도 주석 테이블은 단일 외래 키의 두 열을 모두 참조 할 수 없습니다.
관계형 데이터베이스 디자인 이론에서이 작업을 수행하는 가장 좋은 방법은 두 개의 주석 테이블을 만드는 것입니다. 하지만 분명히 코드를 다시 사용하는 이유 때문에이를 피하기를 원할 것입니다.
가장 직접적인 실용적인 접근법은 주석 테이블에 두 개의 외래 키 열을 넣고 각각의 설명에 대해 하나의 null과 null을 만들면됩니다.
가장 좋은 방법은 다른 방법입니다. 질문에서 "엔티티 ID"를 참조하십시오. 그래서 엔티티 테이블을 만드십시오! 그렇다면 저자와 서적 및 의견은 모두 을 참조하여 표를 참조 할 수 있습니다.
편집 추가 :
필립 켈리, 레이, 그리고 (내가 생각하는) 북극 모든 중 하나 book_id
또는 author_id
및 참조 할 수있는 entity_id
을 추가하여 주석 테이블을 수정 제안 이들 중 어느 것이 참조되는지를 나타내는 일종의 플래그 (각각 char(1)
, tinyint
및 boolean
).
실용적 (데이터 무결성,보고, 효율성 포함) 및 이론적 인 두 가지 이유로 좋은 솔루션이 아닙니다.
가장 중요한 문제는 데이터 무결성 문제입니다. 관계형 데이터베이스 시스템은 항상 자체 데이터의 무결성을 유지 관리해야하며, DB가이를 수행하도록 설계된 자연스럽고 선호되는 방법이 있습니다. 이러한 메커니즘 중 가장 중요한 것 중 하나는 외래 키 시스템입니다. comment.entity_id
열이 book.book_id
및 author.author_id
을 모두 참조하는 경우이 열에 대해 외래 키를 만들 수 없습니다.
확실히, 참조를 검증하기 위해 DML (삽입, 갱신, 삭제) 저장 프로 시저에 점검을 넣을 수 있지만, 세 테이블 모두에 대한 모든 DML 조작이 관련되므로 신속하게 큰 혼란이 될 것입니다.
그러면 효율성 문제가 발생합니다. comment
테이블에 대해 쿼리가 실행될 때마다 author
또는 book
테이블 또는 두 테이블 모두에 대한 조인이 필요합니다. 쿼리 계획 생성 시스템에는 최적화 할 수있는 외래 키가 없으므로 성능이 저하 될 수 있습니다.
그러면보고에서이 체계에 문제가 있습니다. 모든 보고서 생성 시스템은 이런 종류의 시스템에 문제가있을 것입니다. 전문가 프로그래머에게는 이것이 문제가되지 않지만 모든 사용자 특별 보고서는 event_id
이 의미하는 바를 뒤집어 논리를 조롱해야하며 매우 나쁜 거래 일 수 있습니다. 어쩌면이 데이터베이스에서 보고서 생성 도구를 사용하지 않을 것입니다. 그러나 다시 한번, 데이터베이스가 궁극적으로 어디에서 사용될 것인지 아무도 모릅니다. 왜 아무것도 허용하도록 시스템과 협력하지 않습니까?
그러면 이론적 인 문제가 발생합니다.
관계형 데이터베이스 이론에서 각 테이블 ("관계 변수")의 각 행 (즉, "튜플")은 실제 세계에 대한 명제를 나타냅니다. 표를 설계하는 것은 그 명제의 형식을 결정하는 것입니다. 이것이 어떻게 작동하는지 몇 가지 예를 살펴 보겠습니다.
comment (comment_id int, comment_type char(1), entity_id int,
user_id int, comment_text nvarchar(max), comment_date datetime)
/* comment_id identifies a comment (comment_text) that a user (user_id)
has made about a book (entity_id if comment_type = 'B') or author
(entity_id if comment_type = 'A') at a particular date and
time (comment_date).*/
는 여기 열 (또는 "속성")을 두 번 의무를하고있다 entity_id
라는 것은 분명하다. 다른 열에 대한 참조를 제외하고는 실제로 아무 것도 나타내지 않습니다. 이것은 실행 가능하지만 만족스럽지 않습니다.
comment (comment_id int, book_id int, author_id int, user_id int,
comment_text nvarchar(max), comment_date datetime)
/* comment_id identifies a comment (comment_text) that a user (user_id)
has made about a book (book_id if not null) or author (author_id if
not null) at a particular date and time (comment_date). */
이것은 첫 번째 버전에서 가장 많이 누락 된 외래 키를 구입합니다. 그러나 이것은 하나의 주석이 책과 저자 모두를 지칭 할 수 없다면 (여전히 합리적 일 수 있음), 여전히 만족스럽지 않습니다. Nullable 열은 설계에 문제가 있다는 경고 신호이며 여기서도 마찬가지입니다. 점검 제한 조건은 전혀 언급하지 않는 주석을 허용하거나 책과 작성자가 허용되지 않는 경우 모두를 피하기 위해 필요할 수 있습니다. 이론적 관점에서
(따라서, 내 관점 :)) 명확한 최선의 선택이 :
book_comment (book_comment_id int, book_id int, user_id int,
comment_text nvarchar(max), comment_date datetime)
/* book_comment_id identifies a comment (comment_text) that a
user (user_id) has made about a book (book_id) at a particular
date and time (comment_date). */
author_comment (author_comment_id int, author_id int, user_id int,
comment_text nvarchar(max), comment_date datetime)
/* author_comment_id identifies a comment (comment_text) that a
user (user_id) has made about an author (author_id) at a particular
date and time (comment_date). */
보고 최고의 효율성, 데이터 무결성 및 편의성을 제공 할 것이 마지막 옵션을 선택합니다. 그리고 유일한 비용은 DML 저장 프로 시저가 주석을 올바른 테이블에 넣을 필요가 있다는 것입니다. 이는 큰 의미는 아니며 주석이 어쨌든 언급 한 내용을 알아야하기 때문입니다.
도서 또는 작성자의 모든 댓글을 한 번에 다시 읽으려는 계획이라면 다른 디자인을 재현 한 테이블 상단에 쉽게 만들 수 있습니다 (원하는 경우).
create view comments as
select
book_comment_id as comment_id,
book_id as entity_id,
comment_text,
'B' as comment_type
from book_comment
union
select
author_comment_id as comment_id,
author_id as entity_id,
comment_text,
'A' as comment_type
from author_comment
두 개의 다른 테이블에 하나의 외래 키를 지정할 수 없습니다. 플래그가있는 경우에도 유용합니다. –
귀하의 제안 ("나는 CommentorType"을 "Comments"와 같이 열을 추가 할 것입니다.)은 게시하기로 결정하기 전에 제가 향한 경로입니다. 더 쉬운 방법은 없었습니다. 감사합니다. – johnnycakes
댓글에 덧글 유형을 추가하는 것은 좋은 해결책이 아닙니다! 이러지 마! 당신은 그것을 후회할 것입니다! 좋아, 기분이 나아 졌어. 계속 전진 해. –