1

Допустим, таблица "Объект" (см. картинку) будет содержать разные объекты. Под объектом имеется в виду конкретный вариант из множества: гараж, квартира, дача. У них имеются разные атрибуты: площадь, этаж, количество комнат - если это квартира; площадь участка, фундамент, туалет - если это дача.

Идея: вынести в таблицы - по причине имеющихся совершенно разных атрибутов у разных типов объекта (например, у гаража не будет атрибута "площадь кухни", "количество комнат", сколько соток, имеется ли баня в наличии, туалет и т.д.

Таким образом добавим к таблице "Объект" FK на "Тип" объекта. Таблица "Тип" связана связью многим-ко-многим с таблицей "Атрибуты". Так мы можем узнать какие атрибуты есть у конкретного объекта (иначе говоря - какие атрибуты разрешены для конкретного типа объекта). Ну и таблица "Значение атрибута" ссылается как на объекты, так и на атрибуты и содержит значение конкретного атрибута какого-либо объекта (например, "Площадь: 40".

Как избавиться от круговой связи (кольца), чтобы при удалении записи не возникало ошибок?

введите сюда описание изображения

wikk
  • 31
  • 4
    а где вы здесь кольцо увидели? вы стрелками связи нарисуйте и увидите, что проблемы нет. Т.е. если навесить FK и constraints, то при удалении, например, "типа" у вас автоматически удалится "объект", из-за этого удалится "значение атрибута". Далее - из-за удаления "типа" удалится так же и "соответствие между типом и атрибутом". Т.е. никаких проблем с удалением нет. – BOPOH Jan 14 '16 at 08:03
  • если такая структура вас смущает, можно сделать по-другому: для каждого "типа" сделать свою таблицу и хранить атрибуты там. Т.е. удаляется три таблицы (атрибут, его значение и связь с типом), но добавляются другие таблицы, которые друг на друга не ссылаются (есть ссылка только на таблицу "объект"). А в саму таблицу "объект" можно перенести общие для всех типов данные (например, цена, владелец, дата и т.д.) Т.е. вместо "кольца" получится простой граф – BOPOH Jan 14 '16 at 08:11

1 Answers1

3

У вас нет никакого кольца, всё совсем даже наоборот.

Текущая ситуация

Основная проблема вашей схемы в том, что AttrVal может содержать object.type и attr, которые не обязаны быть связаны в TypeAttrs.
Грубо говоря, база не помешает вам указать "площадь огорода" для "квартиры".

Решений мне известно три:

  • Добавить валидацию в приложение, забив на то, что структура в базе сама по себе не обеспечивает целостности данных
  • Добавить валидирующие триггеры на изменение(insert, update) в AttrVal
  • Распространить конфликтующие ключи по таблицам, упаковав их в композитные первичные/уникальные ключи:

    С композитами

    В совокупности с двумя FK:

  • AttrVal(object_id, type_id) -> Object

  • AttrVal(attr_id, type_id) -> TypeAttrs

проблема становится решённой, потому что одно поле type_id фигурирует в обоих ключах.

Но с этим добром, если не база, то ORM не захочет нормально работать.


Связанные вопросы: 1 2

vp_arth
  • 27,179