Скажем, сущность продукта магазина, у него есть общие черты, такие как имя, описание, изображение, цена и т. Д., Которые участвуют в логической практике во многих местах, и (полу) уникальные черты, такие как часы и пляжный мяч, могут быть описаны совершенно по-разному , Так что я думаю, что EAV подойдет для хранения этих (полу) уникальных функций?
Использование структуры EAV для имеет несколько последствий, которые являются компромиссами.
Вы торгуете «меньшим пространством для строки, потому что у вас нет 100 столбцов, которые null
« против »более сложных запросов и модели».
Наличие EAV обычно означает, что значение является строкой, в которую можно вставить любые данные. Это имеет значение для проверки правильности и ограничения. Рассмотрим ситуацию, когда вы указали количество используемых батарей в таблице EAV. Вы хотите найти фонарик, который использует батареи размера С, но менее 4 из них.
select P.sku
from
products P
attrib Ab on (P.sku = Ab.sku and Ab.key = "batteries")
attrib Ac on (P.sku = Ac.sku and Ac.key = "count")
where
cast(Ac.value as int) < 4
and Ab.value = 'C'
...
Здесь нужно понять, что вы не можете разумно использовать индекс для значения. Вы также не можете запретить кому-либо вставлять что-то, что не является целым числом или недопустимым целым числом (использует батарейки -1), поскольку столбец значений используется снова и снова для различных целей.
Это имеет значение при попытке написать модель для продукта. У вас будут хорошие напечатанные значения ... но вы также будете Map<String,String>
просто сидеть там со всеми видами вещей в нем. Это затем имеет дополнительные последствия при сериализации его в XML или Json и сложности попыток проверки или запросов к этим структурам.
Некоторые альтернативы или модификации рассматриваемого шаблона вместо ключа свободной формы должны иметь другую таблицу с допустимыми ключами. Это означает, что вместо сравнения строк в базе данных вы проверяете равенство идентификаторов внешних ключей. Смена самого ключа производится в одном месте. У вас есть известный набор ключей, что означает, что они могут быть выполнены как enum.
Вы также можете иметь связанные таблицы, которые содержат атрибуты определенного класса продукта. В продуктовом отделе может быть другая таблица, с которой связано несколько атрибутов, которые не нужны строительным материалам (и наоборот).
+----------+ +--------+ +---------+
|Grocery | |Product | |BuildMat |
|id (fk) +--->|id (pk) |<---+id (fk) |
|expiration| |desc | |material |
|... | |img | |... |
+----------+ |price | +---------+
|... |
+--------+
Есть моменты, которые особенно требуют таблицы EAV.
Рассмотрим ситуацию, когда вы не просто пишете систему инвентаризации для своей компании, где вы знаете каждый продукт и каждый атрибут. Вы сейчас пишете систему инвентаризации для продажи другим компаниям. Вы не можете знать каждый атрибут каждого продукта - они должны будут определить их.
Одна идея, которая выходит: «мы позволим клиенту модифицировать таблицу», и это просто плохо (вы попадаете в метапрограммирование для структур таблиц, потому что вы больше не знаете, что, где, они могут по- королевски испортить структуру или испортить приложение, у них есть доступ, чтобы делать неправильные вещи, и последствия этого доступа становятся значительными). Есть больше об этом пути в MVC4: Как создать модель во время выполнения?
Вместо этого вы создаете административный интерфейс для таблицы EAV и разрешаете его использовать. Если клиент хочет создать запись для «polkadots», он попадает в таблицу EAV, и вы уже знаете, как с этим справиться.
Пример этого можно увидеть в модели базы данных для Redmine, где вы можете увидеть таблицу custom_fields и таблицу custom_values - это те части EAV, которые позволяют расширять систему.
Обратите внимание, что если вы обнаружите, что вся структура вашей таблицы выглядит как EAV, а не как реляционная, вы, возможно, захотите взглянуть на разновидность KV NoSQL (cassandra, redis, Mongo, ... ...). Поймите, что они часто идут с другими компромиссами в их дизайне, которые могут или не могут соответствовать тому, для чего вы его используете. Тем не менее, они специально разработаны с целью структуры EAV.
Вы можете прочитать SQL против NoSQL для системы управления запасами
Следуя такому подходу с базой данных NoSQL, ориентированной на документы (couch, mongo), вы можете рассматривать каждый элемент инвентаря как документ на диске ... быстро собрать все в одном документе. Кроме того, документ структурирован так, что вы можете быстро извлечь что-то одно. С другой стороны, поиск во всех документах вещей, которые соответствуют определенному атрибуту, может иметь меньшую производительность (сравните, используя 'grep' со всеми файлами) ... все это компромисс.
Другим подходом может быть LDAP, где у каждого будет база со всеми связанными с ней элементами, но затем к нему будут применены дополнительные классы объектов для других типов элементов. (см. Инвентаризация системы с использованием LDAP )
Как только вы пойдете по этому пути, вы можете найти что-то, что точно соответствует тому, что вы ищете ... хотя все идет с некоторыми компромиссами.