Страницы

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

воскресенье, 7 июля 2019 г.

Организация поторяющихся полей в таблицах

В моей практикте часто встречаются проблемы отображения ООП подхода на реляционные базы данных в случае полей одинакового типа в одном классе. Не могу понять как решать такую проблему наиболее эффективным способом.
Более подробный пример:
У меня есть сущность 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. Не нашел там ничего для решения такой проблемы (может плохо искал).
Существуют ли какие-то общие практики, инструменты или механизмы для решения таких проблем?


Ответ

Я так понял, что вопрос состоит в выборе:
Создать в целевой таблице несколько полей - ссылок на какой-то справочник Создать дополнительную табличку, содержащую несколько записей, принадлежащих к одной записи целевой таблицы и ссылки на какой-то справочник (возможно с указанием типа связи и других параметров)

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

В привязке к конкретной схеме адресов - для простоты вполне подходит первый вариант. Если же вдруг понадобится хранить историю изменения адреса, то больше подходит второй. Или вдруг могут появиться дополнительные типы адресов - например адрес доставки, прописки, проживания, почтовый итп.

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

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