2012-02-10 4 views
1

테이블이 Message입니다. 각 메시지는 Invoice 테이블 또는 Rfp 테이블과 연결될 수 있지만 둘 다 연결될 수는 없습니다. 나는이를 구현하는 가장 좋은 방법과 사투를 벌인거야 다음 Message 테이블이 모두 InvoiceRfp 테이블에 대한 foreign 키가하는대체 테이블에 대한 외래 키에 대한 팁이 필요합니다.

  1. 한 가지 방법입니다. 하나의 FK는 유효하지만 다른 하나는 NULL이어야합니다. (단일 테이블 상속.)하지만 이것은 다소 어색한 것처럼 보입니다. 사용되지 않는 열 이외에도 FK가 둘 다 사용되거나 둘 모두 NULL 인 경우를 방지 할 방법을 찾아야합니다. 그리고 이것은 모든 단일 메시지에 대해 반복 될 필요가 있습니다.

  2. 또 다른 접근법은 조인 테이블을 만드는 것입니다. 이 경우 내 Message 테이블은 조인 테이블에 대해 FK를 가지며 InvoiceRfp 테이블도 조인 테이블에 대한 FK를가집니다. 그러나 여기서 문제는 조인 테이블에 대한 참조가 주어지면 관련 FG가 포함되어 있는지 알 수 없기 때문에 관련 Invoice 또는 Rfp 테이블을 찾는 것이 어색합니다. 그래서, 여기서는 관련 테이블을 찾는 방법을 알아야 할 다른 단계에 의지해야합니다. 예를 들어 어떤 테이블이 관련되어 있는지를 나타내는 열을 추가하는 것과 같은 제약 조건을 만드는 것이 어렵습니다.

  3. 마지막으로 두 가지 유형의 테이블을 만들 수 있습니다. 이것은 위에서 설명한 문제를 해결하지만 우리가 어떤 유형인지 모른 채 메시지를 추가해야하는 장소에 논리가 있기 때문에 응용 프로그램에 문제가 발생합니다. (관련 테이블에는 FK 만있을 수 있습니다.)

누구든지 여기에 몇 가지 팁을 제공 할 수 있습니까? 이 방법들 중 어느 것도 이상적은 아니지만 두 가지 중에서 선택할 때 고려하지 못한 부분이있을 수 있습니다. 또는 아마도 더 나은 접근 방식이있을 것입니다.

+0

나는 일반적으로 옵션없이 함께 할 것입니다 ... 하나의 FK가 설정되어 있는지 확인하기 위해 점검 제한 조건을 사용할 수 있습니다. 1 - 네, 두 개의 FK 컬럼을 갖게됩니다. 적어도 하나는 항상 null입니다. 그러나 이것은 제 의견으로는 가장 깨끗하고 명확한 접근법입니다. FK 칼럼에서 여러분이 참조하고있는 것이 명확하고, FK 제약 조건에 대한 참조 무결성을 가질 수 있습니다. –

+0

@marc_s : 그러나 옵션 -2가 더 명확한 (표준화 된) 접근법이 아니겠습니까? "join"테이블은 두 개의 서브 타입 테이블 인'Invoice'와'Rfp'의 상위 타입이 될까요? –

+0

옵션 -2는 [Concrete Supertable] (http://stackoverflow.com/questions/922184/why-can-you-not-have-a-foreign-key-in-a-polorphic-association) 예입니다. Bill Karwin의 대답. –

답변

2

옵션 1에서는

CREATE TABLE [dbo].[Rfp] (Id int IDENTITY(1,1) NOT NULL, PRIMARY KEY CLUSTERED (Id)) 
CREATE TABLE [dbo].[Invoice] (Id int IDENTITY(1,1) NOT NULL, PRIMARY KEY CLUSTERED (Id)) 

CREATE TABLE dbo.[Message] (Id int IDENTITY(1,1) NOT NULL, RfpId int, InvoiceId int, 
    PRIMARY KEY CLUSTERED (Id), 
    FOREIGN KEY (RfpId) REFERENCES [dbo].[Rfp] (Id), 
    FOREIGN KEY (InvoiceId) REFERENCES [dbo].[Invoice] (Id), 
    ) 

ALTER TABLE dbo.[Message] 
    ADD CONSTRAINT CK_FK CHECK ( (RfpId IS NULL AND InvoiceId IS NOT NULL) 
            OR (RfpId IS NOT NULL AND InvoiceId IS NULL)); 
관련 문제