Где хранить данные - инфоблок, highload-блок или своя таблица
Выбираем хранилище под задачу: инфоблок с готовым интерфейсом, highload-блок для больших справочников и своя таблица для собственной структуры данных.
Что нужно знать заранее
Инфоблок даёт готовый интерфейс, права и поиск, но платит за это структурой хранения свойств. На небольших объёмах это незаметно, а на сотнях тысяч записей разница в скорости становится решающей.
Highload-блок задуман под большие справочники с простой структурой полей. У него нет прав на отдельные записи и нет привычного интерфейса редактора, зато выборки работают быстро и предсказуемо.
Своя таблица даёт полную свободу и полную ответственность. Интерфейс, права, кэширование и миграции структуры придётся написать самому, зато схема данных будет ровно такой, какая нужна проекту.
Шаги
- Выяснить, кто ведёт данные: редактор в админке, обмен из учётной системы или код.
- Оценить объём записей и частоту их изменения на горизонте пары лет работы.
- Проверить, нужны ли права на отдельные записи и штатный поиск по содержимому.
- Выбрать хранилище по этим ответам, а не по привычке команды разработчиков.
- Заложить в оценку стоимость переезда, если требования могут заметно измениться.
Решение
Считаем текущие объёмы данных проекта:
SELECT 'элементы', COUNT(*) FROM b_iblock_elementUNION ALL SELECT 'значения свойств', COUNT(*) FROM b_iblock_element_property;-- значений свойств обычно в разы больше самих элементов, и это главная цена инфоблокаЧисло значений свойств отвечает на вопрос о цене хранения лучше любых советов. Каталог на десять тысяч товаров с двадцатью свойствами - это уже двести тысяч строк в таблице значений.
Заводим справочник в highload-блоке:
$result = \Bitrix\Highloadblock\HighloadBlockTable::add([ 'NAME' => 'VendorCity', // имя класса сущности, с большой буквы 'TABLE_NAME' => 'vendor_city', // имя таблицы в базе данных]);// поля справочника добавляют пользовательскими полями к созданной сущностиHighload-блок хорош ровно там, где нужен большой плоский справочник. Города, пункты выдачи, коды скидок и совместимость запчастей ложатся на него отлично, а дерево разделов - уже нет.
Заводим свою таблицу под собственную структуру:
class VendorContractTable extends \Bitrix\Main\ORM\Data\DataManager{ public static function getTableName(): string { return 'vendor_contract'; } public static function getMap(): array { return [ (new \Bitrix\Main\ORM\Fields\IntegerField('ID'))->configurePrimary(true)->configureAutocomplete(true), (new \Bitrix\Main\ORM\Fields\StringField('NUMBER'))->configureRequired(true), new \Bitrix\Main\ORM\Fields\DatetimeField('SIGNED_AT'), ]; }}Своя таблица выигрывает там, где важны собственные индексы и предсказуемый запрос. Договоры, журналы обмена и служебные очереди почти всегда живут именно так, а не в инфоблоках.
Сравниваем скорость выборки на своих данных:
$start = microtime(true);\Bitrix\Iblock\Elements\ElementCatalogTable::getList(['limit' => 500])->fetchAll();printf("инфоблок: %.3f c\n", microtime(true) - $start);// тот же замер повторяют для highload-блока и для своей таблицы на боевых объёмахПланируем переезд заранее:
// прикладной код обращается к репозиторию, а не к конкретному хранилищуinterface CityRepository { public function findByCode(string $code): ?array; }// при смене хранилища меняется одна реализация, а не весь проектПрослойка репозитория делает переезд возможным без переписывания половины проекта. Она же помогает при переходе с инфоблоков на своё хранилище, когда каталог перерастает исходное решение.
Типичные проблемы
Каталог из сотен тысяч записей стал медленным.
Данные лежат в инфоблоке со множеством свойств, и выборка собирает их по частям. Плоские справочники переносят в highload-блок или в свою таблицу.
Редактор не может вести справочник сам.
Данные лежат в своей таблице, интерфейс к которой никто не написал. Для данных, которые ведёт человек, берут инфоблок или универсальный список.
Права на отдельные записи не работают.
Выбран highload-блок, а он прав на записи не поддерживает совсем. Такие требования закрывают инфоблоком или проверками в своём коде.
Поиск по сайту не находит данные.
Своя таблица и highload-блок в поисковый индекс сами не попадают. Их индексацию пишут своим кодом либо переносят данные в инфоблок.
Переезд на другое хранилище встал в месяцы.
Прикладной код обращался к хранилищу напрямую из десятков мест. Обращения прячут за одним классом доступа с первого дня проекта.
Частые вопросы
Когда инфоблок точно лучше?
Когда данные ведёт редактор и нужны права, поиск и привычный интерфейс. Новости, статьи, страницы и обычный каталог живут в инфоблоках без вопросов.
Highload-блок быстрее инфоблока?
На плоских справочниках заметно быстрее, потому что данные лежат в одной таблице. На данных со сложной структурой разница уже не так велика.
Можно ли смешивать хранилища в одном проекте?
Да, и это нормальная практика: каталог в инфоблоке, справочники в highload-блоке, журналы в своей таблице. Главное - не размазывать одну сущность по двум хранилищам.
Что выбрать для журналов и очередей?
Свою таблицу с нужными индексами и своей чисткой по сроку. Инфоблок для такого не предназначен и быстро разрастается.
Как понять, что пора переезжать?
По времени выборок на боевых объёмах и по числу обходных решений в коде. Если каждая новая задача требует костыля, хранилище выбрано неверно.
Смежное
- Свои таблицы на ORM - оглавление подтемы
- Своя таблица на ORM: сущность, запросы, изменение структуры - как заводят своё хранилище
- Highload-блок на практике: создание, поля, привязка к свойству - как устроен большой справочник
- Переезд с самописной таблицы на инфоблоки - обратный переезд и его цена
- Универсальный список: настройка, права и вывод элементов - хранилище для данных, которые ведёт сотрудник
- Выборки из инфоблоков: GetList, ORM и разделы - как выбирают из инфоблока
- Ядро D7: ORM - устройство слоя данных