Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Foreign Key к двум таблицам или к родительской таблице / 9 сообщений из 9, страница 1 из 1
28.12.2016, 19:37
    #39377201
Elfix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
Приветствую.

Есть родительская таблица

contragents
id serial PK;
title_name character varying;


Есть дочерние таблички:

persons
id serial PK; -- унаследовано от contragents
title_name character varying; -- унаследовано от contragents
sex boolean;


organizations
id serial PK; -- унаследовано от contragents
title_name character varying; -- унаследовано от contragents
activity_type_id integer;


Есть независимая таблица

buildings
id serial PK;
owner_id integer;

Мне нужно организовать Foreign Key одним из способов:

1. buildings.owner_id в идеале связать с contragents.id;
2. buildings.owner_id связать с organization.id или c persons.id

Первый способ идеальный. Но при добавлении строки в persons запись в contragents еще не появилась, соответственно возникает проблема - ключ отсутствует и транзакция откатывается.

Второй способ - не знаю как это записывается (возможно ли это вообще?).

Варианты - перепроектировать дизайн базы данных не предлагать.
Заранее благодарен за любую конструктивную помощь.
...
Рейтинг: 0 / 0
28.12.2016, 20:18
    #39377222
vyegorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
Elfix,

Что значит "унаследована"?

Если:
Код: sql
1.
CREATE TABLE persons () INHERITS (contragents);


то при появлении записи в `persons` она должна быть и в `contragents`.

Если не так, то приведите DDL.
...
Рейтинг: 0 / 0
28.12.2016, 21:16
    #39377246
Elfix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
vyegorovElfix,

Что значит "унаследована"?

Если:
Код: sql
1.
CREATE TABLE persons () INHERITS (contragents);

Это и значит.vyegorovто при появлении записи в `persons` она должна быть и в `contragents`.


Это если убрать любые вторичные ключи.
Если же их добавить, то возникает ошибка = ключ 1 не найден.
Т. е. он генерируется, вставляется в дочернюю таблицу, но затем проиходит ошибка и вся транзакция откатывается.
Об этом много написано на форумах, я склонен думать, что это баг. Поэтому ищу способ сделать FK к двум таблицам-исходникам, игнорировав родительскую таблицу.

Как это сделать? И возможно ли это?
...
Рейтинг: 0 / 0
28.12.2016, 21:30
    #39377252
Elfix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
Ну вот листинги:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
CREATE TABLE public.contragents
(
  id integer NOT NULL DEFAULT nextval('contragents_id_seq'::regclass),
  title_name character varying(100) NOT NULL,
  CONSTRAINT contragents_id_pk PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.contragents
  OWNER TO postgres;

CREATE TABLE public.organiations
(
-- Унаследована from table contragents:  id integer NOT NULL DEFAULT nextval('contragents_id_seq'::regclass),
-- Унаследована from table contragents:  title_name character varying(100) NOT NULL,
  activity_type_id integer NOT NULL DEFAULT 0,
  CONSTRAINT organizations_id_pk PRIMARY KEY (id)
)
INHERITS (public.contragents)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.organiations
  OWNER TO postgres;

CREATE TABLE public.persons
(
-- Унаследована from table contragents:  id integer NOT NULL DEFAULT nextval('contragents_id_seq'::regclass),
-- Унаследована from table contragents:  title_name character varying(100) NOT NULL,
  sex boolean NOT NULL DEFAULT true,
  CONSTRAINT persons_id_pk PRIMARY KEY (id)
)
INHERITS (public.contragents)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.persons
  OWNER TO postgres;

CREATE TABLE public.buildings
(
  id integer NOT NULL DEFAULT nextval('buildings_id_seq'::regclass),
  owner_id integer NOT NULL DEFAULT 0,
  CONSTRAINT buildings_id_pk PRIMARY KEY (id),
  CONSTRAINT owner_id_fk FOREIGN KEY (owner_id)
      REFERENCES public.contragents (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.buildings
  OWNER TO postgres;



При добавлении записи в persons ошибки не возникает. В contragents запись появляется. Ключ равен 1. В persons ключ тоже равен 1.

Далее при добавлении записи в таблицу buildings с owner_id = 1 возникает ошибка:
INSERT или UPDATE в таблице "buildings" нарушает ограничение внешнего ключа "owner_id_fk".
DETAIL: Ключ (owner_id)=(1) отсутствует в таблице "contragents".
...
Рейтинг: 0 / 0
28.12.2016, 22:14
    #39377267
vyegorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
Elfix,

Ну да, всё так и должно быть (тупанул):
Код: sql
1.
SELECT * FROM ONLY contragents;


Elfixперепроектировать дизайн базы данных не предлагать
В данном случае желаемого эффекта можно достичь, если сделать обычные таблицы, без наследования.
Но перепроектировать надо будет. Я бы не рекомендовал с наследованием связываться вообще, больше неожиданностей, чем удобства.
...
Рейтинг: 0 / 0
28.12.2016, 22:56
    #39377285
Elfix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
vyegorov,

а есть ли возможность сделать foreign key к двум таблицам-дочерям?
Уверен, что как-то можно, но никак не удается.
...
Рейтинг: 0 / 0
28.12.2016, 23:20
    #39377293
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
Elfixvyegorov,

а есть ли возможность сделать foreign key к двум таблицам-дочерям?
Уверен , что как-то можно, но никак не удается.
зря. наследование в пж -- это довольно мертворожденная штука, так и не нашедшая достаточно сумасшедших поклонников, чтобы сделать её осмысленной. применяется обычно только для партицирования. где--то маргинально ее пользуют якобы по изначальному назначению, но не широко. я как--то давно пользовал для чего--то такого. но удобств особых не наблюл.

как сделать "фк"
делаете "центр звезды" -- отдельно стоящую (обычную, а не наследуемую) таблицу из всех id--иков гирлянды наследования (обвязав те триггерами на пополнение / удаление "центра"). и вот к такому "центру" вяжетесь своими фк. много хенджоба и куча неудобств, в т.ч. не с разбега отладите каскады, думаю. (сами фк так не пытался строить, но поддерживать уникальность id на всей гирлянде удается, если в триггерах не наврёте)
...
Рейтинг: 0 / 0
29.12.2016, 02:26
    #39377340
Elfix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
qwwqнаследование в пж -- это довольно мертворожденная штука, так и не нашедшая достаточно сумасшедших поклонников, чтобы сделать её осмысленной.Еще бы. FK сделать нельзя - и вся логика использования этого чудесного механизма сходит на нет.
В остальном довольно удобно. В случае если поля таблиц будут расширяться, переписывать массу тригеров и проверок будет достаточно сложно. Наследование же - штука прекрасная, но из-за вот таких нелогичных поведений СУБД пользоваться им становится невозможно...
...
Рейтинг: 0 / 0
29.12.2016, 10:33
    #39377430
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Foreign Key к двум таблицам или к родительской таблице
Elfixqwwqнаследование в пж -- это довольно мертворожденная штука, так и не нашедшая достаточно сумасшедших поклонников, чтобы сделать её осмысленной.Еще бы. FK сделать нельзя - и вся логика использования этого чудесного механизма сходит на нет.тут грустно.
можно сделать материальный самопальный объект "центр" с уникью над ним

но нельзя сделать виртуальный объект "центр", с уникъю (абстракцией) над несколькими частичными уникъю -- СУБД таких удобств не предоставляет

ну и нельзя сделать ФК на такой не предоставленный "уникъю" над множеством однотипных индексов.

тут смелых студентов от стоунбрейкера не бегало.

ElfixВ остальном довольно удобно. В случае если поля таблиц будут расширяться, переписывать массу тригеров и проверок будет достаточно сложно. Наследование же - штука прекрасная, но из-за вот таких нелогичных поведений СУБД пользоваться им становится невозможно...

про массу триггеров для поддержания только поля (полей) ключа, и , м.б., партицирующего --- умозаключение неверное. в центре кроме ключа ничего быть не должно. он обслуживает материализованное уникъю для иерархии типов сущностей. только при изменении самого ключа -- будут траблы.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Foreign Key к двум таблицам или к родительской таблице / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]