В моей практикте часто встречаются проблемы отображения ООП подхода на реляционные базы данных в случае полей одинакового типа в одном классе. Не могу понять как решать такую проблему наиболее эффективным способом.
Более подробный пример:
У меня есть сущность Person у которой есть поля address и workAddress. Причем у обоих подсущностей одинаковый набор полей.
В коде это примерно так (псевдокод):
class Person
Address address
Address workAddress
Как реализовывать это с помощью языков программирования понятно. Возникает вопрос как это сделать в БД. Я могу сделать, например, так (псевдо sql):
CREATE TABLE address (id SERIAL PRIMARY KEY);
CREATE TABLE PERSON (
id SERIAL PRIMARY KEY,
address FOREIGN KEY (address.id),
workdAddress FOREIGN KEY (address.id)
);
Это будет работать, но это не совсем правильно с точки зрения теории БД. Ведь у нас будет один-ко-многим со стороны адрес-человек. Даже два раза.
Еще можно пойти таким способом:
CREATE TABLE PERSON (
id SERIAL PRIMARY KEY
);
CREATE TABLE address_type (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE address (
id SERIAL PRIMARY KEY,
person_id FORIGN KEY(person.id),
address_type FORIGN KEY (address_type.id)
);
Здесь мы получаем правильное решение с точки зрения реляционной модели, но из очень плохое решение для ООП. Из минусов тут: дополнительный JOIN, дополнительная таблича с типами, неудобно с этим работать в коде (надо перебрать все адреса для поиска нужного или дополнять селекты).
Искал решение в самом популярном ORM - Hibernate. Не нашел там ничего для решения такой проблемы (может плохо искал).
Существуют ли какие-то общие практики, инструменты или механизмы для решения таких проблем?
Ответ
Я так понял, что вопрос состоит в выборе:
Создать в целевой таблице несколько полей - ссылок на какой-то справочник
Создать дополнительную табличку, содержащую несколько записей, принадлежащих к одной записи целевой таблицы и ссылки на какой-то справочник (возможно с указанием типа связи и других параметров)
Оба варианта хорошие, имеют право на существование.
Какой из них выбрать зависит от требований к решаемой задаче.
Первый вариант можно выбрать в случае, если типы связи двух таблиц жестко фиксированы, не изменяются в процессе работы системы и не предусматривается их дальнейшее расширение. Также, этот вариант решения намного проще, чем второй.
Второй вариант можно выбрать в случае необходимости задания дополнительных параметров связи (тип, видимость, доступность, множественность, приоритетность) и в случае, если предусматривается гибкое управление типами связи этих двух таблиц. Например, теоретически возможно хранение истории изменений связанных данных.
В привязке к конкретной схеме адресов - для простоты вполне подходит первый вариант.
Если же вдруг понадобится хранить историю изменения адреса, то больше подходит второй. Или вдруг могут появиться дополнительные типы адресов - например адрес доставки, прописки, проживания, почтовый итп.
Комментариев нет:
Отправить комментарий