Повторяющийся идентификатор в дочерних таблицах

Мне интересно, каковы плюсы и минусы повторяющегося идентификатора в дочерних таблицах в базе данных.

Например, рассмотрим таблицу 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 во всех дочерних таблицах:

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. Мой вопрос: есть ли другие подходы к решению этой ситуации? Если нет, есть ли способ повторить идентификатор в дочерних таблицах, сохраняя при этом целостность данных?


person cdmckay    schedule 25.03.2014    source источник


Ответы (2)


Я предполагаю, что из вашего примера важно, чтобы отношение было родитель‹-дочерний1‹-дочерний2, а не родительский‹-дочерний1 и родительский‹-дочерний2.

Так как насчет чего-то подобного.

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 можно считать увеличивающимся целым числом, поэтому вы всегда можете определить порядок дочерних элементов.

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)
);
person Kuberchaun    schedule 25.03.2014

Решение @JustKim в порядке, но вы можете пойти еще дальше

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

Если parent_id имеет значение null, эта запись является родительской.

Конечно, чтобы получить всех дочерних элементов одного родителя, вы должны использовать рекурсию в своем коде.

person Kenan Zahirovic    schedule 25.03.2014