澄清註釋之後,您似乎只需將主鍵存儲在各種驗證表中。 (您沒有使用人工或代理鍵。如果「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');
相關http://stackoverflow.com/q/517417/369489 –
所以索賠表需要有相應的行中的一個,只有表EmailVerification,元代碼,並CertificateFile之一? –
那麼電子郵件,Metacode和證書必須互相排斥嗎?因此,如果通過電子郵件提出索賠#1,那麼Metacode和證書都不會將索賠#1作爲外鍵? – KacireeSoftware