powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Подскажите, как реализовать связь таблицы с несколькими другими.
17 сообщений из 17, страница 1 из 1
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129250
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задался вопросом, парсинг интернета результата не дал.

Есть 2 таблицы, таблица "Предподаватели" и таблица "Студенты" (если совсем просто, то обе таблицы содержат по 2 поля - айдишник и ФИО). И есть третья таблица "Календарь" где ведется учет мероприятий.

Вопрос, в таблице календарь владельцем мероприятия может быть как студент так и предподаватель. Есть ли возможность связать поле таблицы Календарь с полями из 2 таблиц? Т.е. выбор или этот или тот.

Пример чисто теоритический, я понимаю что проще преподов и студентов объединить в одну таблицу, проставить признак isPrepod и объединить один ко многим.

Знаю что на базах типа Монго можно сделать. Интересует именно SQL

Вопрос, есть ли возможность связать именно с 2 таблицами? Может не Postgresql?
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129255
Фотография mefman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
igor2022
Задался вопросом, парсинг интернета результата не дал.

Есть 2 таблицы, таблица "Предподаватели" и таблица "Студенты" (если совсем просто, то обе таблицы содержат по 2 поля - айдишник и ФИО). И есть третья таблица "Календарь" где ведется учет мероприятий.

Вопрос, в таблице календарь владельцем мероприятия может быть как студент так и предподаватель. Есть ли возможность связать поле таблицы Календарь с полями из 2 таблиц? Т.е. выбор или этот или тот.

Пример чисто теоритический, я понимаю что проще преподов и студентов объединить в одну таблицу, проставить признак isPrepod и объединить один ко многим.

Знаю что на базах типа Монго можно сделать. Интересует именно SQL

Вопрос, есть ли возможность связать именно с 2 таблицами? Может не Postgresql?

foreign key чем не устраивают?
В чем проблема вообще?
Реляционные базы на то и реляционные что строятся вокруг сущностей и связей между ними.
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129256
Misha111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
связать форейнкеем или в запросе?
если в запросе то коалесцем через (скаляр или лефт оутер джоин)
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129289
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mefman, не то чтоб не устраивает. Спасибо за наводку, пошел читать.

Misha111, пока вопрос архитектурно связать, на уровне БД.
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129316
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Создаем таблицу Преподов, 2 поля - ИД и ФИО

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TABLE IF NOT EXISTS public."Prepods"
(
    "Id" integer NOT NULL,
    "FIO" text COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT "Prepods_pkey" PRIMARY KEY ("Id")
)

TABLESPACE pg_default;

ALTER TABLE public."Prepods"
    OWNER to igor;



Заполняем данными:

1, Препод Петров
2, Препод Иванов

Создаем аналогичную таблицу студентов, 2 поля - ИД и ФИО

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TABLE IF NOT EXISTS public."Students"
(
    "Id" integer NOT NULL,
    "FIO" text COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT "Students_pkey" PRIMARY KEY ("Id")
)

TABLESPACE pg_default;

ALTER TABLE public."Students"
    OWNER to igor;



Заполняем данными:

3, Студент Вася
4, Студент Петя

И создаем 3 таблицу Календарь, 3 поля - ИД, текстовая запись о событии и поле владелец (вот тут как-раз владельцем события может быть или студент или препод)

-- Table: public.Calendar

-- DROP TABLE public."Calendar";

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE TABLE IF NOT EXISTS public."Calendar"
(
    "Id" integer NOT NULL,
    text text COLLATE pg_catalog."default",
    owner integer,
    CONSTRAINT "Calendar_pkey" PRIMARY KEY ("Id"),
    CONSTRAINT owner_p FOREIGN KEY (owner)
        REFERENCES public."Prepods" ("Id") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID,
	CONSTRAINT owner_s FOREIGN KEY (owner)
        REFERENCES public."Students" ("Id") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID
)

TABLESPACE pg_default;

ALTER TABLE public."Calendar"
    OWNER to igor;


Заполняем данными:

1, Совещание, 1 (все проходит хорошо)
2, Учеба, 3 (при сохранении получаю ошибку "ERROR: insert or update on table "Calendar" violates foreign key constraint "owner_p"
DETAIL: Key (owner)=(3) is not present in table "Prepods".")

При этом если первой строчкой приписываю студента, то все ок, но при попытке добавить 2 строкой препода получаю ту же ошибку но "(owner)=(1) is not present in table "Students".")"


Т.е. если я вписал студента, то следующей строкой не дает вписать препода и наоборот.


Тот результат который я хочу получить:

1, Совещание, 1 (Препод Петров)
2, Учеба, 3 (Студент Вася)
3, Попить пивка, 4 (Студент Петя)
4, Экзамен у Васи, 1 (Препод Петров)

Пните плиз в нужном направлении :-)))
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129323
Ы2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
igor2022, все логично же: вы наложили на одно поле два ограничения, соответственно, оба они должны выполняться, т.е. в случае внешних ключей вставляемое значение должно присутствовать в обеих таблицах.
Ограничения связаны с помощью «и», а не «или».
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129326
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ы2, а как быть если требуется именно ИЛИ?
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129331
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
igor2022
Ы2, а как быть если требуется именно ИЛИ?
отказаться от FK, а проверку на целостность делать в триггере
типа такого

пс
но одна таблица Persons всё-таки лучше
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129334
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
court,
в моем примере лучше, совершенно согласен. Но это просто пример... На самом деле стоит задача разобраться как правильно организовать хранение остатков в БД. Пытаюсь разобраться как организовать что-то наподобие регистров в 1С (там в строке, в поле "Регистратор" могут быть ссылки как на приходные накладные так и на расходные, списания, возвраты - и это все разные документы и в первую очередь разные таблицы где они хранятся.

Как-то же они это хранят...
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129337
Фотография mefman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
igor2022
court,
в моем примере лучше, совершенно согласен. Но это просто пример... На самом деле стоит задача разобраться как правильно организовать хранение остатков в БД. Пытаюсь разобраться как организовать что-то наподобие регистров в 1С (там в строке, в поле "Регистратор" могут быть ссылки как на приходные накладные так и на расходные, списания, возвраты - и это все разные документы и в первую очередь разные таблицы где они хранятся.

Как-то же они это хранят...

Очень подозреваю что одноце очень много логики хранит внутри самой одноце.
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129339
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
igor2022
Как-то же они это хранят...
там есть (по крайней мере так было в 7.7.) одна общая "шапочная" таблица для ВСЕХ документов
и в регистре храниться идентификатор из этой табл. - http://www.script-coding.com/v77tables.html#1.2.4.
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129340
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
igor2022
Пытаюсь разобраться как организовать что-то наподобие регистров в 1С

кстате

3.4.1. Общее описание подсиcтемы регистров
http://www.script-coding.com/v77tables.html#3.4.1.
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129350
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
court,

если говорить о "шапочной" таблице, то возвращаясь к примеру делаем таблицу Owners куда собираем преподов и студентов...
И возвращаемся к тому же вопросу:

id. owner_id
1 (а вот тут опять таки или студент или препод)

что ведет нас к вопросу как сделать ссылку на 2 таблицы с выбором значения "ИЛИ"


Видел решение на postgres+mongo, там доки в монго в одной коллекции, и в скуль пишется просто ссылка на док в монго.

Но блин 1С как-то хранит без МонгоДБ.

Регистры в 1С это OLAP, хранятся пачкой таблиц в самой БД. Но там такая структура что черт ногу сломит.
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129352
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
За ссылку спасибо, ушел читать ))
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129365
igor2022
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так, вот еще накопал https://infostart.ru/1c/articles/1061227/
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129419
delphinotes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вариант 1. Сделайте два столбца, один ссылается на преподов, другой - на студентов
добавьте триггер, который будет проверять, что заполнено только одно из двух полей.
Вариант 2. Одна таблица и на преподов и студентов. Если они там по другим атрибутам не сильно отличаются, то тоже не плохо.
Вариант 3. "Над" таблицами преподов и студентов создаётся ещё одна таблица с двумя полями: ID, тип (препод/студен). Плюс единый генератор/сиквенс на обе сущности.
Форейн ключи - из календаря, из преподов, из студентов - все на обобщённую.
Такой себе результат, но позволит сэкономить на столбцах в календаре, если сущностей на самом деле очень много.
Целостность при удалении студентов/преподов нужно поддерживать на триггерах, но триггеры эти тривиальны - они работают только с "новой" таблицей.
Вариант рабочий, когда таблиц типа календарь - несколько.
Вариант 4.
В календарь тоже можно добавить столбец "тип", чтобы в джойнах не ходить в третью таблицу. Это также даст возможность иметь разные сиквенсы для преподов и студентов, просто форейн кей из календаря будет составным (по двум полям).
Вариант 5. Без доп. таблицы но со столбцом "тип" в календаре. Целостность - на триггерах, но если таблиц типа "календарь" не одна, то с добавлением ещё одной таблицы нужно обновлять и триггеры.

Вариантов много, всё зависит от конкретной задачи, но самый ПОНЯТНЫЙ - это первый, те, кто будет это потом поддерживать, только спасибо скажут, что не сделали по другому.
...
Рейтинг: 0 / 0
Подскажите, как реализовать связь таблицы с несколькими другими.
    #40129772
maxkar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
delphinotesВариант 1. Сделайте два столбца, один ссылается на преподов, другой - на студентов
добавьте триггер, который будет проверять, что заполнено только одно из двух полей.

Полностью поддерживаю! Только я бы сделал это через check constraint. Что-то в духе "CONSTRAINT (single_ref) CHECK (prepod_id IS NOT NULL) != (student_id IS NOT NULL)". Ну и добавить к нему комментарий с описанием, что именно происходит.

delphinotesВариант 5. Без доп. таблицы но со столбцом "тип" в календаре. Целостность - на триггерах, но если таблиц типа "календарь" не одна, то с добавлением ещё одной таблицы нужно обновлять и триггеры.

Тип удобно использовать и при отдельных столбцах для каждой связи. Особенно если потенциальных (но взаимоисключающих) связей несколько. Получается достаточно унифицированный код для проверки:

Код: plsql
1.
2.
3.
4.
CONSTRAINT (proper_ref) CHECK
  ((link_type = 1) AND (prepod_id IS NOT NULL)) OR
  ((link_type = 2) AND (student_id IS NOT NULL)) OR
  ((link_type = 3) AND (some_other_id IS NOT NULL)) OR ...


При этом еще и все cascade на внешних ключах работают.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Подскажите, как реализовать связь таблицы с несколькими другими.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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