2

Есть 2 пары таблиц.

Некий справочник:

  • A (id)
  • A_Component(id, a_id)

И произвольная выборка из этого справочника:

  • B (id, a_id)
  • B_component(id, b_id, ac_id)

UML

Очевидно, что эта структура замыкается в ромб, где средствами базы не обеспечивается целостность данных - ничто не заставляет поля B.a_id и A_Component.a_id совпадать, а хотелось бы.

Ещё раз: необходимо, чтобы B_C.b_id и B_C.ac_id указывали на одну и ту же сущность A.

Вижу пару возможных решений:

  • исключить таблицу B, тем самым разорвав ромб зависимостей.
    решение не подходит, потому что в B есть ещё данные, относящиеся ко всей выборке целиком
  • набор триггеров/ограничений, которые будут валидировать корректность данных в создаваемом B_Component.
    этот метод порождает пару запросов в базу для валидации.

Существует ли более каноничный/элегантный способ для подобной структуры?

vp_arth
  • 27,179
  • 1
    Разве что в A_C и B вместо суррогатного ключа использовать какой нибудь реальный, составной, включающий в себя a_id и ссылаться на них соответственно так же набором полей. но решение так себе – Mike Aug 21 '17 at 07:44
  • И иногда решения подкидывает реальный мир под который строится схема, но по данной абстракции таких решений не найдется – Mike Aug 21 '17 at 07:51
  • предположим, что это A(пицца), A_C(топпинги, применимые к этой пицце), B(пицца в заказе), B_C(топпинги пиццы в заказе). В этом случае у Вас вообще ошибочная схема данных, объединяющая шаблон создания экземпляра сущности и созданный экземпляр - связи A-B и A_C-B_C не существуют, их следует удалить. – Akina Aug 21 '17 at 08:01
  • 1
    @Akina видимо ТС хочет проконтролировать на уровне БД, что добавить в заказ можно только ингредиенты из шаблона – Mike Aug 21 '17 at 08:05
  • @Mike ТС хочет проконтролировать на уровне БД, что добавить в заказ можно только ингредиенты из шаблона Да пусть контролирует... хотя куда как разумнее просто организовать процессы так, чтобы не было возможности внесения в экземпляр заказа нешаблонизированных экземпляров ингредиентов. Но в любом случае связывать готовую пиццу и рецепт на неё - нельзя. – Akina Aug 21 '17 at 08:10
  • Убрать эти связи - вполне себе решение, однако придётся клонировать кучу данных из A/A_C в B/B_C. Денормализация, все дела... Неприятие этой связи также не вполне понятно. Вполне себе *прототипное наследование. Допустим, пицца эта ещё не готова, а лишь заказана. И оперативное изменение этой заказанной пиццы при изменении шаблона для нас плюс(допустим :) ). Другое дело оплаченная готовая пицца - там можно всё сериализовать и хранить в камне. Напомню, пицца - первый пришедший в голову пример подобного справочника* – vp_arth Aug 21 '17 at 08:20
  • @vp_arth Akina имел ввиду, что если вы сохраняете связь с шаблоном, то шаблон вы больше никогда в жизни не поменяете. Например вы перестали закупать шпинат и вам надо убрать его из шаблонов. А уже ранее были заказы в которые он был включен. Если связи в БД жесткие то вы не сможете удалить его из шаблонов – Mike Aug 21 '17 at 08:26
  • Это очевидно, да. В контексте задачи не принципиально. Пусть, шаблоны иммутабельны - новый рецепт - новый шаблон. – vp_arth Aug 21 '17 at 08:29
  • @D-side, составные первичные ключи? В этом что-то есть) Спасибо – vp_arth Aug 21 '17 at 08:31
  • 1
    @vp_arth Я про составные первичные ключи написал первым же комментом. вы почему то не прореагировали, думал не устроило ибо минусы в этом то же есть, не всегда можно найти адекватный ключ – Mike Aug 21 '17 at 08:33
  • @Mike, нет, скорее не понял, о каких ключах речь. Спасибо. – vp_arth Aug 21 '17 at 08:35

1 Answers1

1

Очевидно, что эта структура замыкается в ромб, где средствами базы не обеспечивается целостность данных - ничто не заставляет поля B.a_id и A_Component.a_id совпадать.

Это ошибочное утверждение. Чтобы оно было правильным, необходимо, чтобы было обеспечено соответствие значений B.a_id и A_Component.a_id (т.е. эти таблицы должны быть связаны между собой).

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

Akina
  • 31,807
  • Ок. Вероятно, терминологически я где-то неправ. Но каким образом ваш ответ решает проблему? "чтобы было обеспечено соответствие значений" - в этом и вопрос. Как? – vp_arth Aug 21 '17 at 07:48