Да! вполне возможно иметь многозначные атрибуты атрибутов в EAV.
На самом деле это проще, чем в традиционной реляционной модели, в которой необходимо либо создать дополнительный столбец, либо сохранить несколько значений в формате сортировки с разделителями; оба таких подхода имеют дополнительную сложность при запросе базы данных для заданного значения базового поля (атрибута).
Самый простой способ иметь несколько значений - это просто иметь дополнительную запись значений! (как показано в вопросе)
Кроме того, структура хранилища EAV может быть изменена для явного размещения нескольких значений:
- дополнительное логическое поле в таблице attribute , чтобы указать, может ли поле быть многозначным. (Кстати, аналогичные свойства атрибута также можно кодифицировать, например, требуется ли атрибут или нет и т. Д.
- В таблице значение можно получить дополнительный столбец для указания порядкового номера значения (для всех не многозначных атрибутов устанавливается значение 0 или 1, в противном случае - увеличенное целое число).
Как уже говорилось, эти изменения в физической схеме хранилища EAV не являются необходимыми, но их можно использовать для обеспечения соответствия данных (логической) схеме, а также для отображения нескольких значений многозначных атрибутов. в определенном порядке и т. д.
Редактировать : (подробности о реализации многозначных и / или составных ("объектоподобных") атрибутов)
Если вы абсолютно уверены, что множественные значения ["sub" -], которые составляют атрибут (или аналогично множеству частей, которые составляют атрибут "тип объекта"), являются полностью атомарными, то есть никогда не будут искать или отображаться (или .. .) по отдельности вы можете хранить такой атрибут «наборы значений», как одну запись в таблице значений, кодируя множество значений в одну строку; Для этого на ум приходит JSON или XML-at-large, и он кажется особенно интересным для очень расширяемого / универсального, но любой другой формат, который вы можете анализировать и выводить надежным способом, также будет работать (например, формат с разделителями).
Более «естественным» (EAV-мудрым) способом хранения таких «частей значения атрибута» является их индивидуальное хранение (в нескольких записях таблицы значений, возможно, с полем последовательности, как было указано ранее). Этот подход позволяет обрабатывать «части» в некоторых контекстах, как если бы они были атрибутами.
В обоих случаях вам нужно изменить таблицу атрибутов, чтобы добавить необходимые свойства и типы кодов, чтобы описать такие атрибуты из нескольких частей. Аналогично подходу хранения данных (в таблице значений), вы можете сделать запись атрибута так, чтобы вся информация для данного атрибута [multi-part] была сохранена в одной записи атрибута, или, [и это как правило, проще и гибче] вы можете создать один атрибут на деталь, плюс один атрибут, чтобы «связать их вместе» (например, со свойством, которое содержит строку, разделенную каждым значением идентификатора атрибута подчастей.
Например :
Составным атрибутом для металлических элементов труб может быть диаметр, состоящий из двух частей: числовое значение и код единицы (миллиметр или дюйм).
При первом подходе:
- в таблице атрибутов будет одна запись с типом, указывающим, что это многозначное значение, и свойством расширения, которое будет содержать [упорядоченный] список типов отдельных подчастей.
- в таблице значений будет одна запись, содержащая закодированное значение, такое как, скажем, «0,75 | Inch» (или <diam>0.75</diam><unit>Inch</unit>
).
При втором подходе:
- в таблице атрибутов будет 3 записи: запись или тип числовые с именем скажем «diamvalue», запись типа string с именем «unit» и запись составного имени типа «Diameter»; эта последняя запись будет как-то иметь ссылку на идентификатор двух других атрибутов (на ум приходит простая строка с разделителями-запятыми)- в таблице значений должно быть две записи, по одной для каждого значения diamvalue и атрибутов модуля (такие записи будут иметь дополнительное поле, называемое скажем «parent», содержащее AttributeID атрибута «Diameter». При желании может быть также запись значения для атрибута «Диаметр» [Лично я нахожу это избыточным со свойством «родителя».
Как указывалось ранее, основным преимуществом второго решения является то, что [когда это уместно] можно запрашивать каталог для определенного набора элементов на основе значения части атрибута, например, для поиска всех каналов, которые имеют метрику Блок. Такие запросы разрешаются на уровне SQL, поэтому при первом подходе SQL должен будет сканировать все значения атрибута для атрибута «Диаметр» и анализировать значение для поиска кода модуля.
Картинка стоит тысячи слов; -)
На этой диаграмме показана возможная схема с примерами данных для «второго подхода».
Entity
id | name | description
-- | ---- | ------------
1 | configuration1 | configuration1
Attribute
id | name | type | Required | Repeats | SubAttribIdList
-- | ---- | ---- | -------- | ------- | ---------------
1 | att1 | string | N | N | null (only applicable to composite types)
2 | att2 | int | Y | N | null
3 | att3 | string | Y | Y | null
4 | DiamValue | numeric | Y | N | null
5 | Unit | string | Y | N | null
6 | Diameter | composite| N | N | 4,5
Value
id | entityId| attributeId | ParentAttribId |SeqNr | value
-- | --------| ----------- | -------------- |----- | -----
1 | 1 | 1 | null | 1 | a
2 | 1 | 2 | null | 1 | 1
3 | 1 | 3 | null | 1 | b (this value and next show show a repeating attribute)
4 | 1 | 3 | null | 2 | c
5 | 1 | 3 | null | 3 | d
6 | 1 | 4 | 6 | 1 | 0.75 (this value and next one shows a composite attribute
7 | 1 | 5 | 6 | 1 | Inches
Несколько заметок:
- SeqNr для значений идентификаторов 6 и 7 равен 1 для обоих. Их порядок неявен для SubAttribIdList. Если для атрибута id 6 был задан атрибут с несколькими значениями («Repeats»), у объекта могут быть дополнительные парные последовательности из двух значений, упорядоченные в паре 2, 3 и т. Д.
- Порядковый номер для неповторяемых атрибутов установлен на 1, систематически, также может быть НЕДЕЙСТВИТЕЛЕН, это не применимо.
- свойство «Обязательное» атрибута не фигурирует в многозначном или составном вопросе; Я просто добавил его, поскольку он обычно используется, чтобы помочь приложению (или уровню доступа к объектам) обеспечить соблюдение различных правил целостности.
- Некоторые из вариантов дизайна в этом макете подразумевают максимум 1 уровень включения для составных атрибутов (составной не может быть включен в составной), а также предотвращают включение в составной атрибут многозначного атрибута. Этих ограничений можно избежать с помощью правильной структуры (и с некоторой добавленной сложностью на уровне доступа), но более простая схема, как правило, является приемлемой (атрибуты, которые потребовали бы такую причудливую структуру, часто указывают на недостаток в логической схеме) .