コメントを明確にした後、主キーをさまざまな検証テーブルに格納するだけでよいようです。(人工キーまたは代理キーを使用する必要はありません。「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);
最初の 2 つの挿入は成功します。「EmailVerifications」の PRIMARY KEY 制約により、3 番目の制約が失敗します。
insert into Claims values (43);
insert into EmailVerifications values (43, 1034);
insert into EmailVerifications values (43, 450);
以下は、明確化された要件と一致しません。その継続的な存在をボーナスと考えてください。
私の理解が正しければ、Claims の各行を 0 行で参照するか、1 行だけで参照する必要があります。
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;
「クレーム」で重複する PRIMARY KEY および UNIQUE 制約が必要です。他のテーブルは列 "claim_id" と "verification_code" のペアを参照しますが、列のペアに UNIQUE 制約がない限り参照できません。
validation_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');