我们有一个Claim实体,可以通过aEmailVerification、将MetaCode放到相关网站或上传CertificateFile来证明。现在的问题是,claimer可以选择使用菜单中的方法的任何组合来证明他们的声明,但是在每个类别中,他们只能得到一次机会。含义:

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

所以这是有效的:
 Claim #20 --> EmialVerification #12
 Claim #20 --> MetaCode (none)
 Claim #20 --> CertificateFile #124

还有:
 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与2EmailVerifications有关。
现在我陷入了表模式的困境,因为我不知道如何最好地建模一个0..1关系:
四个带有人工pks(整数id)的独立表,并与通常的1..*关系一样
四个单独的表,但只有一个表有一个id,另外三个表使用这个id作为Claim表的pk和fk。
简单地将其他3个表聚合到Claim表中,并使用Null表示缺少关系?
还有别的吗?
编辑:问题不是很清楚:Claim中的一行可以连接到其他3个表中的0(根本没有连接)或1行,但是Claim中的任何一行不能连接到其他3个表中的多行(如示例中的第3种情况)。
编辑一个可怕的错别字隐藏在阴影中(Claim #34在每个示例的第一行被错误地输入为Claim #43)!!!真的很抱歉。我认为正确的答案仍然有效。

最佳答案

在澄清注释之后,您似乎只需要将主键存储在各种验证表中。(您不必使用人工或代理密钥。如果“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”的主键约束将使第三个失败。
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;

“索赔”中需要重叠主键和唯一约束。其他表引用列对“claim_id”和“verification_code”,除非对列有唯一的约束,否则不能这样做。
验证代码及其检查约束保证外键引用来自正确的表。
-- 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');

关于database - 1-> 0..1关系该怎么办?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16011259/

10-09 18:57