Как мне построить отношения между моими таблицами?

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

Projects -> Sites -> Jobs -> Phases -> Teams

Каждая из них является таблицей в базе данных и имеет отношение к своему родителю.

Я планирую построить Предметы таблица, которая будет содержать общую информацию о том, как мы будем выставлять счета за работу, выполняемую на каждом из этих уровней, то есть имя, цена по умолчанию, единица измерения и т. д.

Затем пользователь создаст Модель выставления счетов что они могут связать список Предметы чтобы, так что они могут быть многоразовыми.

Здесь мои вопросы вступают в игру. Когда пришло время выставить счет, мне нужно сообщить Модель выставления счетов на один из вышеупомянутых уровней. Я не хочу создавать таблицу связывания для каждого из этих уровней с моделью фактурирования. Я хотел бы как-то сохранить целостность отношений между таблицами. Но также, если есть что-то еще, что я могу выставить в будущем, я не хочу вносить существенные изменения в базу данных и / или изменить код, чтобы учесть этот новый «оплачиваемый уровень».

Могу ли я сохранить целостность отношений, не создавая новую таблицу для связи моделей выставления счетов с уровнем?

0

Решение

Могут быть реализованы полиморфные отношения, которые решают проблему присоединения «n» числа различных типов объектов.

Недостатком полиморфных отношений, насколько я знаю, является невозможность реализации без некоторой потери ссылочной целостности.

Хорошее чтение на этом будет https://hashrocket.com/blog/posts/modeling-polymorphic-associations-in-a-relational-database. Одной из самых популярных и простых реализаций будет Полиморфное соединение, цитируемое из статьи ниже:

Полиморфные соединения

Простой подход для подключения ACL к ресурсу состоит в использовании двух
столбцы в таблице acl: resource_type и resource_id. Этот подход
был популяризирован Ruby on Rails. Таблица ACL может быть определена как
следующим образом:

create table acl(
id serial primary key,
resource_type varchar not null,
resource_id integer not null,
-- other fields omitted
unique(resource_id, resource_type)
);

Запрос для получения acl для идентификатора документа: 42 был бы похож на
следующий:

select *
from acl
where resource_type='document'
and resource_id=42;

Серьезная проблема с этим подходом — база данных очень ограничена.
в целостности данных это может обеспечить из-за отсутствия внешнего ключа
ограничения. Это может гарантировать, что ресурс имеет не более одного acl, но
это все. Ресурсу может не хватать acl, а acl может указывать на
недостающий ресурс.


Метод Exclusive Belongs To — это хороший метод повышения ссылочной целостности, но для каждого возможного типа объекта потребуется новый столбец. Цитируется из статьи:

Эксклюзив Принадлежит (AKA Exclusive Arc) В этой модели у acl есть внешние ключи ко всем таблицам, к которым он может принадлежать.

create table acl(
id serial primary key,
document_id integer references document,
image_id integer references image,
file_id integer references file,
report_id integer references report,
-- other fields omitted
check(
(
(document_id is not null)::integer +
(image_id is not null)::integer +
(file_id is not null)::integer +
(report_id is not null)::integer
) = 1
)
);

create unique index on acl (document_id) where document_id is not null;
create unique index on acl (image_id) where image_id is not null;
create unique index on acl (file_id) where file_id is not null;
create unique index on acl (report_id) where report_id is not null;

Обратите внимание на ограничение проверки. Это гарантирует, что ACL принадлежит
ровно один ресурс любого типа. С этим дизайном ACL не может быть
осиротевший, но нет способа принудительно установить, что ресурс имеет ACL.
Также важны частичные уникальные индексы. Ограничение уникального
индексы только к ненулевым значениям значительно экономят место, а также
сокращение операций записи при вставке.

1

Другие решения

Чтобы четко ответить на ваш вопрос, вы не можете сохранить реляционную целостность, не создав по крайней мере еще две таблицы, одну для хранения реляционных идентификаторов между вашей Моделью и вашими Элементами и другую для хранения всех данных для Элементов, которые вы хотите создать, в этом Если у вас останется еще две таблицы, но боль в будущем будет излечена сейчас.

0

По вопросам рекламы [email protected]