Есть база данных (postgresql), содержащая три таблицы -
Люди (ID, Имя, Фамилия, Отчество, Наименование),
Организации (ID, Наименование, Адрес, Расчетный счет),
Автомобили (ID, Марка, Модель, Пробег, Владелец).
Суть проблемы:
Необходимо создать связи между автомобилями и владельцами. Владельцем автомобиля может быть как человек (запись в таблице Люди), так и организация (запись в таблице Организации).
Вопрос:
Каким образом можно осуществить данную связь? Может ли внешний ключ быть полиморфным и, следовательно, каким образом во время JOIN узнать с какой таблицей объединятся(как хранить информацию о типе во внешнем ключе)?
PS:
Заранее извиняюсь за, возможно, глупый вопрос, и прошу учесть, тот факт, что с SQL и РБД как таковыми только познакомился, и есть острая необходимость решить вышеуказанную проблему в крайне короткий срок.
Update:
В первой версии вопроса не указал общее поле - Наименование - в случае если Владелец - человек, его Наименование - например, Иванов И.И.
В качестве примера приведу вымышленный код, думаю так будет понятней:
SELECT Авто.Марка, Авто.Модель, Наименование FROM Авто
INNER JOIN Авто.Внешний_ключ_владельца.Таблица ON Авто.Внешний_ключ_владельца.ID = Авто.Владелец.ID
И возможный результат:
"Daewoo" "Nexia" "Иванов. И.И."
"Ford" "Focus" "ООО ТОРГОПТ"
"Schevrolet" "Camaro" "Сидоров С.В."
Ответ
Структура данных должна быть такой, чтобы запросы по ней были максимально простыми. Если вам в вашем запросе нужно только Наименование от владельца, то в разделении людей и организаций нет никакого смысла. Это должна быть одна таблица Владельцы. Дополнительные поля могут быть как в той же таблице, так и в дочерних типа "данные юрлиц"/"данные физлиц". Все зависит от запросов, сравните ваш вариант:
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 для фио для организаций.
Если вы планируете более сложную логику запросов (которую вы в вопросе не указали) то идите от нее. И идите путем простоты.
Комментариев нет:
Отправить комментарий