Страницы

Поиск по вопросам

понедельник, 23 декабря 2019 г.

Полиморфизм в реляционных БД. Возможно ли?

#sql #база_данных #полиморфизм


Есть база данных (postgresql), содержащая три таблицы - 
Люди (ID, Имя, Фамилия, Отчество, Наименование), 
Организации (ID, Наименование, Адрес, Расчетный счет), 
Автомобили (ID, Марка, Модель, Пробег, Владелец). 
Суть проблемы:
Необходимо создать связи между автомобилями и владельцами. Владельцем автомобиля
может быть как человек (запись в таблице Люди), так и организация (запись в таблице
Организации).
Вопрос:
Каким образом можно осуществить данную связь? Может ли внешний ключ быть полиморфным
и, следовательно, каким образом во время JOIN узнать с какой таблицей объединятся(как
хранить информацию о типе во внешнем ключе)?
PS:
Заранее извиняюсь за, возможно, глупый вопрос, и прошу учесть, тот факт, что с SQL
и РБД как таковыми только познакомился, и есть острая необходимость решить вышеуказанную
проблему в крайне короткий срок.
Update:
В первой версии вопроса не указал общее поле - Наименование - в случае если Владелец
- человек, его Наименование - например, Иванов И.И.
В качестве примера приведу вымышленный код, думаю так будет понятней:

SELECT Авто.Марка, Авто.Модель, Наименование FROM Авто
INNER JOIN Авто.Внешний_ключ_владельца.Таблица ON Авто.Внешний_ключ_владельца.ID
= Авто.Владелец.ID


И возможный результат:
"Daewoo" "Nexia" "Иванов. И.И."
"Ford" "Focus" "ООО ТОРГОПТ"
"Schevrolet" "Camaro" "Сидоров С.В."
    


Ответы

Ответ 1



Структура данных должна быть такой, чтобы запросы по ней были максимально простыми. Если вам в вашем запросе нужно только Наименование от владельца, то в разделении людей и организаций нет никакого смысла. Это должна быть одна таблица Владельцы. Дополнительные поля могут быть как в той же таблице, так и в дочерних типа "данные юрлиц"/"данные физлиц". Все зависит от запросов, сравните ваш вариант: select cars.*, persons.fullname from cars join persons on cars.owner = persons.id and cars.isorg = 0 union all select cars.*, orgs.fullname from cars join orgs on cars.owner = orgs.id and cars.isorg = 1 и запрос с одной таблицей: select cars.*, owners.fullname from cars join owners on cars.owner = owners.id Если вам понадобятся все дополнительные поля в этом запросе (надо еще придумать как их красиво выводить в одной таблице) вы получите одни и те же данные: будут null для людей в адресе и расчетном счете, и null для фио для организаций. Если вы планируете более сложную логику запросов (которую вы в вопросе не указали) то идите от нее. И идите путем простоты.

Ответ 2



Я бы предложил добавить в таблицу Автомобили поле "Тип Владельца", и в нем хранить лишь два варианта: "чел" и "орг". В зависимости от содержимого этого поля связывать поле Владелец либо с таблицей Людей, либо Организаций.

Комментариев нет:

Отправить комментарий