Довольно распространён третий, последний, вариант кратности связи – связь «многие-ко-многим».
О связи говорят, что она имеет кратность «многие-ко-многим», если каждый элемент сущности А может ссылаться одновременно на несколько элементов сущности Б, а каждый элемент сущности Б может ссылаться одновременно на несколько элементов сущности А. | ||
Например, бывают ситуации, когда книга пишется не одним автором, а в соавторстве с другими авторами. В этом случае получается, что:
В Visio связь «многие-ко-многим» непосредственно нарисовать нельзя. Данные сущностей, находящихся в отношении «многие-ко-многим», на бумаге обычно изображают в виде так называемой таблицы-шахматки (матрицы). От обычных (плоских) таблиц они отличаются тем, что имеют шапку не только сверху, но и справа. На пересечениях отмечают существующие связи.
Книги\Авторы | Иванов И. И. (1937 г.р.) | Петров П. П. (1920 г.р.) | ||
«Основы мармитологии», 1982 | √ | √ | ||
«Мармитология и жизнь», 2008 | √ |
| ||
«Бухгалтерия – это скучно?», 1990 | √ |
| ||
Таблица сравнения редакций Битрикса – это тоже типичная шахматка. Так, слева находится список модулей, сверху – список редакций, а на пересечениях указывается, входит ли данный модуль в данную редакцию. | ||
При переходе от инфологической модели к даталогической от связей «многие-ко-многим» непременно избавляются: для этого есть несколько способов.
Первый, самый примитивный, способ используется на практике крайне редко. В одну таблицу помещают данные обеих сущностей. Данные каждого автора дублируют столько раз, сколько он написал книг, а книгу столько раз, сколько авторов над ней работало. В следующем примере жирным шрифтом выделены избыточные данные. В данном случае их объём невелик, но ведь вместо них могли бы оказаться и данные типа «большой текст» – например, краткое содержание книг.
Книга | Год выхода книги | Автор | Год рождения автора | ||
Основы мармитологии | 1982 | Иванов И. И. | 1937 | ||
Основы мармитологии | 1982 | Петров П. П. | 1920 | ||
Мармитология и жизнь | 2008 | Иванов И. И. | 1937 | ||
Бухгалтерия – это скучно? | 1990 | Иванов И. И. | 1937 | ||
Если, например, выяснится, что автор Иванов родился, не в 1937-м, а в 1940-м, то нужно будет внести изменения сразу в несколько строк. Если вдруг из ассортимента магазина будет исключена книга «Основы мармитологии», то придётся удалить более одной строки. При этом информация об авторе Петрове также будет утрачена, так как он не написал других книг – а ведь снятие с продажи книги не всегда означает, что с сайта должна пропасть информация об её авторе.
Очевидно, что такого способа хранения данных следует избегать.
Таблица (инфоблок) находится в 4NF, если она находится в 3NF – и вставка/удаление/модификация строки таблицы не требует изменения других строк таблицы. | ||
Существуют также и другие нормальные формы, но они в применении к Битриксу представляют собой больше академический, чем практический интерес, поэтому здесь не рассматриваются.
Для приведения к 4NF создают «развязочную» зависимую сущность. Так же, как и при дискриминации, она не имеет смысла без существования основных сущностей.
Так, если сущности А и Б связаны с кратностью «многие-ко-многим», то создаётся «развязочная» сущность с именем А_Б, содержащая внешние ключи сущностей А и Б. При этом совокупность этих внешних ключей является первичным ключом сущности А_Б.
Все три сущности могут быть напрямую отображены в три таблицы БД.
На следующем рисунке видно, что у сущности Авторы_Книги первичный ключ составной – и оба его компонента являются внешними ключами (FK) исходных сущностей Авторы и Книги. Связи между сущностями теперь имеют кратность «один-к-одному». И если понадобится изменить год рождения автора, то будет изменена лишь одна строка сущности Авторы. При снятии с продажи одной книги будет удалена лишь одна строка из сущности Книги, никоим образом не затронув сущность Авторы (об удалении строк из Авторы_Книги чуть позже).
Зависимая сущность, помимо служебной информации о связях основных сущностей, может также нести и осмысленную дополнительную информацию в неключевых атрибутах. Эта информация всегда характеризует не элементы сущностей, а является характеристикой связи между двумя конкретными элементами основных сущностей.
Так, предположим, нам нужно хранить информацию о том, какой автор получил какой гонорар за работу над данной книгой и каков был его вклад в общее дело. При использовании бумажной шахматки мы бы заменили галочки на данные о гонораре и вкладе.
Книги/Авторы | Иванов И. И. (1937 г.р.) | Петров П. П. (1920 г.р.) | ||
«Основы мармитологии», 1982 | 15 000 руб. | 20 000 руб. | ||
соавтор | основной автор | |||
«Мармитология и жизнь», 2008 | 16 000 руб |
| ||
основной автор | ||||
«Бухгалтерия – это скучно?», 1990
| 24 000 руб. |
| ||
основной автор | ||||
Согласитесь, достаточно громоздко? Однако в модели всё выглядит значительно красивее: достаточно добавить два неключевых поля Гонорар и ВкладВРаботу в сущность Авторы_Книги.
В случае Битрикса, в принципе, можно также использовать отображение в три инфоблока. Однако это крайне неэффективно по той причине, что, как вы помните, первичным ключом у Битрикса всегда является ID.
В поля инфоблока поместить внешние ключи не удастся, а свойства вообще хранятся во внешней таблице. Естественно, выборки из физической БД будут не самыми производительными. Более того, поддерживать целостность данных придётся самостоятельно, а вводить данные без разработки специального интерфейса будет крайне затруднительно. | ||
К счастью, в Битриксе есть понятие множественных свойств, не характерное для реляционных баз данных. Так, в одном свойстве можно хранить несколько значений.
Множественное ссылочное свойство заменяет собой «развязочную» таблицу: по сути, оно и есть логическая таблица, у которой первый столбец – всегда ID текущего элемента, а второй стобец – ID’ы элементов, на которые он ссылается.
Сложность использования множественных полей в том, что придётся определиться, для какого именно инфоблока из двух связываемых будет создаваться множественное ссылочное свойство.
В некоторых случаях, однако, используют перекрёстные ссылки, создавая множественные ссылочные свойства в каждом из инфоблоков, ссылающиеся друг на друга. Это может быть очень эффективным решением с точки зрения производительности, когда полные выборки во всю ширину инфоблока производятся с одинаковой частотой из обоих инфоблоков. Однако это требует существенных усилий на поддержание целостности данных (в случае подобной связности трёх и более инфоблоков сложность поддержки целостности возрастает лавинообразно). Например, если редактор сайта создаёт в инфоблоке А элемент и привязывает его к элементу инфоблока Б, то при сохранении должно сработать событие, которое автоматически привяжет соответствующий элемент инфоблока Б к элементу инфоблока А (разумеется, нужно поддержать и вариант, когда редактор изменяет элемент инфоблока Б, а элемент инфоблока А изменяется автоматически). При этом – внимание! – необходимо будет обеспечить механизм, который при автоматическом изменении элемента инфоблока Б не запустит изменение инфоблока А, то есть не допустит зацикливание. Поэтому рекомендуем использовать этот подход только при серьёзной необходимости и отличном понимании принципов работы обработчиков событий. | ||
Следует определиться, какая из двух сущностей «больше похожа» на классификатор, а какая – на классифицируемую сущность. Как правило, почти на всех сайта классификатор используется только в виде списка (в связи с чем обычно и имеет только самые необходимые атрибуты: ID и Наименование). Тогда как классифицируемая сущность предназначена для просмотра больше на детальной странице, чем в списке.
В нашем примере книжного Интернет-магазина авторы используются, в основном, для отбора книг, то есть в качестве классификатора (на детальную страницу автора заходят значительно реже, чем на детальную страницу книги), тогда как книги представляют наибольшую смысловую ценность – и выступают в роли классифицируемой сущности.
Для облегчения выбора можно также представить себе, что было бы, если бы свойство было не множественным. Так, например, легко представить, что книга пишется только одним автором (в большинстве случаев так оно и есть), а вот представить, что во всём ассортименте магазина каждый автор написал только по одной книге, достаточно сложно.
В итоге, правило одно: множественное свойство следует размещать в том инфоблоке, в составе которого оно чаще будет отображаться на сайте. В нашем примере следует разместить его в инфоблоке Книги.
При задании имени множественного свойства следует использовать существительное не в единственном, а во множественном числе (разумеется, для ссылочных свойств оно должно совпадать с именем инфоблока-классификатора).
В Visio для изображения множественного свойства используется условное обозначение [LIST].
Для того чтобы поставить отметку [LIST], следует выбрать на панели свойств нужное свойство, нажать кнопку Edit, выбрать вкладку Collection и отметить Ordered group of values (List) – напоминаем, именно этому варианту списка значений соответствует множественное поле Битрикса.
Бывают ситуации, когда один и тот же классификатор выступает для классифицируемой сущности в разных качествах. Пусть, например, существуют сущности Мероприятия и Компании. У мероприятий есть организаторы и участники. И одна и та же компания может выступать для одного и того же мероприятия и как организатор, и как участник одновременно. В этом случае свойства-ссылки должны содержать в своём имени имя классификатора (в единственном или множественном числе – в зависимости от того, множественное ли свойство), а также роль этого свойства.
| ||
Читатели, знакомые с системой «1С:Предприятие», наверняка заметят аналогию с табличными частями документов (версии 7.7 и 8) и справочников (только 8). По сути дела, множественные свойства Битрикса – это табличные части 1С, но имеющие только один столбец.
Для большинства ситуаций одного столбца хватает. Однако в том случае, когда надо указать не только наличие связи, но и её характеристики (как в примере с гонорарами), приходится изворачиваться вплоть до использования неэффективного решения с отображением в три инфоблока. Однако есть вариант лучше.
Поскольку множественные свойства в Битриксе де-факто являются упорядоченными наборами значений, можно создавать столько дополнительных множественных свойств, сколько дополнительных атрибутов будет у связи.
Внимание! Нам не известен ни один документ, в котором Битрикс официально оговаривал бы тот факт, что множественное свойство – это именно упорядоченный набор значений. Поэтому, как говорится, этот способ вы можете использовать только «на свой страх и риск»: способ весьма и весьма эффективный, хотя и недокументированный. | ||
Например, можно создать в инфоблоке Книги два дополнительных множественных свойства: Гонорары и ВкладыВРаботу. Тогда первый элемент в списке авторов будет соответствовать первому гонорару и первому вкладу, второй автор – второму гонорару и второму вкладу и т.д.
Опытный редактор даже сможет использовать для редактирования стандартную форму редактирования элемента, но это будет довольно неудобно (хотя и не смертельно), и возможно появление ошибок ввода. Для избежания этого придётся делать специализированную форму ввода, предназначенную специально для редактирования набора множественных свойств как одной таблицы.