2013-04-15 52 views
2

我們有一個Claim實體,可能會被EmailVerificationMetaCode放入相關網站或上傳CertificateFile。現在的問題是,請求者可能會選擇通過使用任何方法的組合來證明他們的主張,但在每個類別中他們只有一個鏡頭。含義:如何處理1→0..1的關係?

Claim -- 0..1 --> EmialVerification 
Claim -- 0..1 --> MetaCode 
Claim -- 0..1 --> CertificateFile 

所以這是有效的:

也是這樣:

Claim #34 --> EmialVerification (none) 
Claim #34 --> MetaCode (none) 
Claim #34 --> CertificateFile (none) 

這樣的:

Claim #34 --> EmialVerification #1034 & #450 
Claim #34 --> MetaCode (none) 
Claim #34 --> CertificateFile (none) 

因爲#43是相關ŧ兩個EmailVerification s。

現在我被困在表模式,因爲我不知道如何最好地建模0..1關係:

  • 四連人工的PK(整數ID)單獨的表去,因爲是平常用1 .. *關係
  • 四個單獨的表,但只有一個有一個id和其他3個使用這個id作爲他們自己的PK和FK到Claim表?
  • 只是簡單地將其他3個表彙總到Claim表中並使用Null來表示缺少關係?
  • 別的東西?

EDIT正如它出現的問題不是很清楚:在Claim一排可以在任何的其他3,但被連接至0(完全不連接的)或1行任何單列中Claim可以而不是可以連接到任何其他3個表中的多個行(如示例中的第三種情況)。

編輯一個可怕的錯字是潛伏在陰影中(Claim #34被輸入在每個例子中的第一行錯誤地爲Claim #43)! 。真對不起。我認爲正確的答案依然如此。

+0

相關http://stackoverflow.com/q/517417/369489 –

+0

所以索賠表需要有相應的行中的一個,只有表EmailVerification,元代碼,並CertificateFile之一? –

+0

那麼電子郵件,Metacode和證書必須互相排斥嗎?因此,如果通過電子郵件提出索賠#1,那麼Metacode和證書都不會將索賠#1作爲外鍵? – KacireeSoftware

回答

1

澄清註釋之後,您似乎只需將主鍵存儲在各種驗證表中。 (您沒有使用人工或代理鍵。如果「claim_num」是一個自然的關鍵,它的VARCHAR(15),用「claim_num」。)

create table Claims (
    claim_id integer primary key, 
    other_columns_go_here char(1) not null default 'x' 
); 

create table EmailVerifications (
    claim_id integer primary key references Claims (claim_id), 
    email_verification_num integer not null unique, 
    other_columns_go_here char(1) not null default 'x' 
); 

create table MetaCodes (
    claim_id integer primary key references Claims (claim_id), 
    metacode_num integer not null unique, 
    other_columns_go_here char(1) not null default 'x' 
); 

create table CertificateFiles (
    claim_id integer primary key references Claims (claim_id), 
    certificate_file_num integer not null unique, 
    other_columns_go_here char(1) not null default 'x' 
); 

這些插入會成功。

insert into Claims values (20); 
insert into EmailVerifications values (20, 12); 
insert into CertificateFiles values (20, 124); 

前兩個插入將成功。 「EmailVerifications」上的PRIMARY KEY約束會使第三個失敗。

insert into Claims values (43); 
insert into EmailVerifications values (43, 1034); 
insert into EmailVerifications values (43, 450); 

下列不符合要求的澄清。考慮它的持續存在獎金。

如果我理解正確,您希望聲明中的每一行都由零行引用,或者僅由一行引用。

create table Claims (
    claim_id integer primary key, 
    verification_code char(1) not null 
    check (verification_code in ('c', 'e', 'm')), 
    unique (claim_id, verification_code), 
    other_columns_go_here char(1) not null default 'x' 
); 

create table EmailVerifications (
    claim_id integer not null, 
    verification_code char(1) not null default 'e' 
    check (verification_code = 'e'), 
    primary key (claim_id, verification_code), 
    foreign key (claim_id, verification_code) 
    references Claims (claim_id, verification_code), 
    other_columns_go_here char(1) not null default 'x' 
); 

create table MetaCodes (
    claim_id integer not null, 
    verification_code char(1) not null default 'm' 
    check (verification_code = 'm'), 
    primary key (claim_id, verification_code), 
    foreign key (claim_id, verification_code) 
    references Claims (claim_id, verification_code), 
    other_columns_go_here char(1) not null default 'x' 
); 

create table CertificateFiles (
    claim_id integer not null, 
    verification_code char(1) not null default 'c' 
    check (verification_code = 'c'), 
    primary key (claim_id, verification_code), 
    foreign key (claim_id, verification_code) 
    references Claims (claim_id, verification_code), 
    other_columns_go_here char(1) not null default 'x' 
); 

begin; 
    insert into Claims values (1, 'c', 'x'); 
    insert into CertificateFiles values (1, 'c', 'x'); 
commit; 

begin; 
    insert into Claims values (2, 'e', 'x'); 
    insert into EmailVerifications values (2, 'e', 'x'); 
commit; 

begin; 
    insert into Claims values (3, 'm', 'x'); 
    insert into MetaCodes values (3, 'm', 'x'); 
commit; 

「Claims」中重疊的PRIMARY KEY和UNIQUE約束是必需的。其他表引用一對列「claim_id」和「verification_code」,除非在這對列上有一個UNIQUE約束,否則它們不能這樣做。

verification_code及其CHECK約束條件保證外鍵引用來自右表。

-- This insert will fail. 
-- Inserting into EmailVerifications requires 'e', not 'c'. 
begin; 
    insert into Claims values (4, 'c', 'x'); 
    insert into EmailVerifications values (4, 'c', 'x'); 
commit; 

-- This insert will fail. (Duplicate row.) 
insert into EmailVerifications values (2, 'e', 'x'); 

-- This insert will fail. (Trying to make two rows reference one row in Claims.) 
insert into CertificateFiles values (2, 'e', 'x'); 
+0

+1在證明表中巧妙地使用PK來施加..1約束。是否有可能發信號通知RDBMS(假設有問題的特定服務器支持這種情況)證明表中的PK實際上是FK到'Claim'的? –

+0

@ ashy_32bit:好的。首先我應該做到這一點。我對今天和明天的面試有太多的想法。更新的代碼。 –

+0

請您根據第二個編輯重新閱讀這個問題:-D? –