Добрый день!
Появилась необходимость запилить механизм универсальных каталогов, с возможностью создавать/изменять каталоги, их разделы и свойства элементов. Есть опыт работы с Bitrix и его инфоблоками, и совсем немного сталкивался с узлами и CCK в Drupal.
Хочу узнать какие есть ещё варианты решения такой задачи. Возможно это какие-то бандлы для Symfony, или плагины в Composer. Если таковых нет, то очень помогут советы по структуре БД:
1. стоит ли разделять элементы из разных каталогов в отдельные таблицы, или хранить их в одной, как делает Bitrix
2. где размещать свойства элементов, которые будут создаваться пользователем через какой-нибудь интерфейс (отдельные таблицы со значениями свойств (инфоблоки Bitrix), добавление новых колонок в таблицу элементов (хайлоад блоки в Bitrix), если отдельные таблицы то оптимально ли делать их для каждого свойства в отдельности (как в Drupal))
3. ...
Желательно что бы такая структура могла без сильного скрипа и треска работать с большим количеством элементов (например 200+ тыс.), производить выборку с фильтрацией и разбивкой для постраничной навигации в одном запросе.
Вангую - щас понабегут люди с советами типа "юзай mongodb"...
Вообще можно использовать EAV. Это когда атрибуты сущности хранятся не горизонтально (столбцы в таблице), а вертикально (один атрибут - одна строка). Дополнительно нужны таблицы, которые будут хранить список типов сущностей, список типов атрибутов и связи типов сущностей и типов атрибутов.
Но предупреждаю - есть ощутимое проседание по быстродействию, да и работать с этим может быть не так удобно.
В случае, когда необходимо соорудить хранилище для однотипных сущностей с опциональными атрибутами, например каталог товаров, где всё есть товар, но у холодильника есть мощность, а у смартфона - количество мегапикселей это в самый раз.
Так вот, в таком случае быстродействие по фильтрации достигается через создание отдельного индекса, может даже с использованием отдельного ПО, такого как Sphinx.
Ну или можно запариться и сделать конструктор таблиц в админке сайта. Т.е. ты в админке накликиваешь атрибуты в сущность, жмёшь "сохранить" и сервер формирует запрос create table...
Иван Корюков: т.е. грубо говоря, товары в одной таблице, их атрибуты в другой. в таблице атрибутов:
- id товара
- id св-ва
- значение
ну и атрибуты джойнятся к товарам через id-товара?
Если говорить о товарах, то использование EAV-подобной системы это классика. При постраничном отображении оверхед не очень большой, а если кешировать, то и вовсе минимальный.
Оперирование таблицами больше подходит для случаев, когда создаются не однотипные сущности с фиксированным количеством атрибутов - как раз как инфоблоки битрикса, которые могут быть чем угодно. Насколько помню как раз у битрикса хайлоад инфоблоки делаются через таблицы.
Иван Корюков: да, у Bitrix хайлоад-блоки это отдельные таблицы, но у инфоблоков там некий гибрид. EAV используется только у атрибутов множественного типа, а одиночные хранятся в ещё одной отдельной таблице, где каждая колонка это отдельный атрибут.
А что на счёт подхода у Drupal? там вроде как тоже что-то вроде EAV, только отдельная таблица создаётся для каждого атрибута. Есть какие-то преимущества у такого подхода?
Тут уже чистая математика. Когда у вас все атрибуты в одной таблице, то во время запроса с условием, СУБД проходит по каждой строке и смотрит чтобы она подходила, получается O(n). Естественно, если разбить эту одну таблицу на m штук, то и обрабатываться будет меньше строк - грубо говоря O(n/m).
Мы думали об этом, когда у нас в таблице атрибутов стало больше 3 млн. записей.
Дальше мыслей дело не пошло, т.к. было решено отказаться от EAV, но не потому что было найдено лучшее решение, а из-за того, что EAV не была нужна вовсе, т.к. не было сущностей с переменным числом атрибутов.