子表中重复的id

时间:2014-03-25 23:06:52

标签: sql database postgresql data-integrity

我想知道数据库中子表中重复id的优缺点。

例如,考虑一个表parent

create table parent (
  id int,
  a text,
  b text
)

parent有一个引用它的child1表:

create table child1 (
  id int,
  parent_id int not null references parent(id),
  c text,
  d text
)

一切都很好,没什么特别的。当你继续向下钻研时,问题出现了:

create table child2 (
  id int,
  child1_id int not null references child1(id),
  e text,
  f text
)

create table child3 (
  id int,
  child2_id int not null references child2(id),
  g text,
  h text
)

我遇到的问题是,你越往下走,加入你的方式就越乏味。我考虑过的一个解决方案是在所有子表中重复parent id:

create table child2 (
  id int,
  parent_id int not null references parent(id),
  child1_id int not null references child1(id),
  e text,
  f text
)

create table child3 (
  id int,
  parent_id int not null references parent(id),
  child2_id int not null references child2(id),
  g text,
  h text
)

这有助于减少连接数,但也会影响数据库完整性。如果您切换parent_id的父级,则需要始终记住更新所有child1列。我的问题是:有没有其他方法来处理这种情况?如果没有,有没有办法在子表中重复id,同时仍然保持数据完整性?

2 个答案:

答案 0 :(得分:1)

我假设你的例子很重要,关系是父母< -child1< -child2而不是父< -child1和父< -child2。

那么这样的事情怎么样。

create table parent 
(
  id int,
  a text,
  b text
);

create table child 
(
  id int,
  parent_id int null references parent(id),
  previous_child_id int null references child(id)
  c text,
  d text
);

更加规范化的第二种方法就是这样。这假设parent_child上的id可以假设为一个递增的整数,所以你总是可以计算出孩子的顺序。

create table parent 
(
  id int PRIMARY KEY,
  a text,
  b text
);

create table child 
(
  id int PRIMARY KEY,
  parent_id int null references parent(id),
  previous_child_id int null references child(id)
  c text,
  d text
);

create table parent_child
(
  id serial PRIMARY KEY,
  parent_id int null references parent(id),
  child_id int null references child(id)
);

答案 1 :(得分:0)

@JustKim的解决方案没问题,但你可以更进一步

create table person
(
  id int,
  parent_id int null references person(id),
  c text,
  d text
);

如果parent_id为null,则该记录为parent。

当然,为了获得一个父母的所有孩子,你必须在你的代码中使用递归。