Sql 嵌套一对多关系上的唯一约束

Sql 嵌套一对多关系上的唯一约束,sql,postgresql,Sql,Postgresql,假设我试图表示三种类型的事物——祖父母、父母和孩子。祖父母和父母之间是一对多的关系,父母和孩子之间是一对多的关系。共享祖父母的父母必须有唯一的名字。儿童也是如此,因为所有祖父母相同的儿童都必须有一个唯一的名字 下面是一个示例模式: 创建表祖父母( 祖父母ID文本主键, uniquefield1文本不为空 ); 创建表父级( parentid文本主键, 祖父母ID文本引用祖父母, 名称文本不为空, uniquefield2文本不为空, 唯一(祖父母ID、姓名) ); 创建表子项( childid文

假设我试图表示三种类型的事物——祖父母、父母和孩子。祖父母和父母之间是一对多的关系,父母和孩子之间是一对多的关系。共享祖父母的父母必须有唯一的名字。儿童也是如此,因为所有祖父母相同的儿童都必须有一个唯一的名字

下面是一个示例模式:

创建表祖父母(
祖父母ID文本主键,
uniquefield1文本不为空
);
创建表父级(
parentid文本主键,
祖父母ID文本引用祖父母,
名称文本不为空,
uniquefield2文本不为空,
唯一(祖父母ID、姓名)
);
创建表子项(
childid文本主键,
祖父母ID文本引用祖父母,
parentid文本引用父对象,
名称文本不为空,
uniquefield3文本不为空,
唯一(祖父母ID、姓名)
);
我正试图想出一些方法来消除对
child
表中
grandrentid
字段的需要,因为我不想陷入与
parentid
字段内容不一致的情况。但是,我不能仅仅删除它(据我所知),因为我仍然需要对
祖父母ID
姓名
进行唯一约束


同样值得注意的是,每一代人都有独特的信息。这是一个有点做作的例子,因为实际的用例是特定于领域的,只会混淆问题。

您需要避免不由数据库而是由应用程序控制的冗余。应用程序中的一个bug可以存储数据中难以解决的差异。如果控制得当,冗余是可以的

您需要在
child
表中包含
祖父母ID
列,以确保子集中name列的唯一性。现在,要考虑的关键问题是,在<代码>父< /代码>表中,可以从<代码>子< /代码>表中引用“强”>复合键<强>表。这样,您将能够在
子表中强制执行唯一性,并确保数据库始终验证冗余

例如:

create table grandparent (
  grandparentid text primary key,
  uniquefield1 text not null
);

create table parent (
  parentid text not null,
  grandparentid text not null references grandparent (grandparentid),
  name text not null,
  uniquefield2 text not null,
  unique (parentid, grandparentid), -- added this key
  unique (grandparentid, name)
);

create table child (
  childid text primary key,
  grandparentid text not null,
  parentid text not null,
  name text not null,
  uniquefield3 text not null,
  unique (grandparentid, name),
  foreign key (parentid, grandparentid) 
    references parent (parentid, grandparentid)
);
请注意最后一行:

  foreign key (parentid, grandparentid) 
     references parent (parentid, grandparentid)
此外键引用父表中的唯一约束


使用此结构,您将无法插入
祖父母ID
父母ID
的错误组合。数据库不会有它。

只需删除它即可。您可以通过父级访问它。就我所知,我仍然无法确保孩子的名字在祖父母ID中是唯一的。我会将所有世代存储在同一个表中。由于有一个母亲列和一个父亲列,两个都是fk。不幸的是,每个表实际上代表不同的东西,所以我不能将它们全部放在同一个表中。很抱歉没有在原始问题中包括这一点,我已对其进行了修改以反映这一点。您的意思是大多数/许多人将存储在多个表中吗?用不同的身份证。非常混乱。