Изучая проблему одного проекта, подумал, что число 13 000 может стать хорошим подспорьем в вопросе выбора правильной архитектуры проекта на битрикса. Но об этом числе чуть позже.
[spoiler]
Сначала необходимо прояснить терминологию.
Что входит в понятие архитектуры
Мы говорим, что Битрикс представляет из себя
Любой наш модуль разрабатывается исходя из реальных жизненных потребностей. Мы собираем различные сценарии работы определенного функционала, выбираем наиболее общие черты и проектируем внутреннюю структуру модуля на основе этих данных.
Иными словами, если мы говорим, например, про модуль блогов, это блоги, а не какое-то абстрактное "нечто", которое что-то пишет в базу данных и что-то читает. Т.е., конечно, можно (а часто и нужно) переделывать интерфейсы стандартных модулей под свои задачи, но всегда надо помнить о том, для чего они были сделаны.
Т.е. лучше любой модуль, любой компонент, любую форму использовать по назначению.
Практическая сторона
Занимался проблемой одного проекта, где сильно тормозит стандартный компонент форума. Сайт специфический, форумы там выполняют особую задачу. Оказалось, что на этом проекте заведено 13 000 форумов (не топиков, а именно форумов)!
В результате кеш компонента списка форумов оказался 45 Мб. Я стал смотреть глубже, оказалось, что даже АПИ пока не позволяет выполнить ограничение выборки форумов. И в этом нет ничего странного: тысячи сайтов работают на форуме битрикса и до сих пор не сталкивались с такой проблемой.
Задача программиста при разработке сайта состояла в том, чтобы группировать темы комментариев (в действительности, несколько сложнее, но суть не в этом). На тот момент заводить для этого новый форум казалось логично, и это хорошо работало, пока их были десятки или сотни. А теперь проект запущен в боевую эксплуатацию, набрал контент, и вносить архитектурные изменения очень тяжело.
Выпускать архитектурно неправильные решения нельзя!
И вот теперь я подхожу к тому, ради чего делался этот пост. Анализируя эту ситуацию, прихожу к выводу, что для того, чтобы избежать подобных ошибок, не обязательно иметь большой опыт работы с Битриксом, проектирования и пр.
Обратитесь к тем данным проекта, которые будут создаваться автоматически скриптами, пользователями или контент менеджерами. Речь о тех сущностях, число которых будет постоянно расти. Не пытайтесь предугадать, насколько они вырастут за пол года, задайте себе вопрос: а как будет работать проект если их будет 13 000?
В большинстве случаев можно ответить на него на основе общих соображений. Например, можно говорить о том, что не будет проблем (или они будут относительно легко решаемые) если речь идет об элементах инфоблоков, топиках форума, постов в блоги, пользователях, подписчиках в рассылках и т.д.
Если есть сомнения, обязательно проведите практический тест, надолбив как можно более правдоподобные данные скриптом.
CModule::IncludeModule('forum'); for($i=0;$i<13000;$i++) { $arFields = array( 'NAME' => 'Форум '.$i, 'DESCRIPTION' => 'Здесь содержится тестовое описание форума '.$i ); CForumNew::Add($arFields);} |
Примеры ситуаций из жизни
Если вернуться к задаче с форумом. Таблица списка топиков содержит дополнительное поле SOCNET_GROUP_ID, которое содержит ID группы соцсети. Его можно использовать для дополнительной фильтрации по топикам. А если бы даже его не было, лучше расширить структуру таблиц модуля, например, создав свою таблицу связку: топик - группа. При этом, конечно, не надо увлекаться дальше с тем, чтобы переписать ядро модуля для доступа к своей таблице. Надо из неё получать данные прямым запросом, а из стандартных таблиц - через АПИ.
Другой случай. На одном довольно серьёзном проекте потребовалось сохранять историю ip адресов голосования за элемент инфоблока. Разработчики решили для этого использовать множественное свойство элемента. Когда записей стало порядка 13 000, работать с формой редактирования элемента не было никакой возможности. А правильно было бы: хранить ip адреса в отдельном инфоблоке или в своей таблице.
Инфоблоки вообще довольно сложная тема. Часто можно встретить когда для инфоблока заводят несколько сотен свойств. Причина простая: продаваемый товар содержит все эти характеристики. Помните, что следует выносить в отдельные свойства только те характеристики, по которым будет происходить фильтрация. Остальные следует внести в описание товара в виде текста.
Другой причиной чрезмерного обилия свойств может быть объединение разного рода товаров в одном инфоблоке. Каждый товар добавляет свои характеристики. Выносите такие товары в отдельные инфоблоки. Ведь никто не будет делать сравнение, скажем, холодильников и телефонов (телефон всегда будет в выигрыше: мало потребляет, габариты меньше, а размер экрана больше, да и стоит дешевле )
А в одной гос. организации ведется архив многомегабайтных документов. Разработчики решили использовать для этого поле инфоблока "Детальный текст". При редактировании таких элементов в визуальном редакторе вешался браузер. Лучше всё же для таких задач использовать полноценный офлайновый редактор, а в инфоблоке хранить привязку к файлу на диске.
Всё сейчас не вспомню, да это и не важно, поэтому перехожу к заключительной части.
Резюме
На Битриксе можно сделать любой сайт, но он не освобождает вас от необходимости думать. Если для решения задачи требуется применить решение, которое не будет работать на 13 000 записях, не делайте его. Меняйте архитектуру!
Но есть и обратный момент.
Иногда отдельный элемент проектируется под определённые требования и нужды. Однако в процессе эксплуатации (хорошо если через 2-3 года, а если через полгода?) как в том анекдоте "концепция меняется".
И тогда неожиданно оказывается, что спроектированный элемент (свойство инфоблока, включаемая область в вёрстке) не подходит (переполняются свойства или ячейка вёрстки рвёт интерфейс).
И не всегда имеется возможность заранее знать о том, что так будет.
Вот сходу только про вёрстку пример приходит, когда заказчик неожиданно начинает хотеть 3 номера телефона вместо одного, но того же размера - ну некуда их вместить оказывается! НЕКУДА! А разработчик может и предусмотрел место для 2, но не для 3... И он был прав, поскольку иначе в вёрстке была бы слишком заметная "дыра".
Но слова золотые - подписываюсь под каждым!
Но доделать всегда легче, чем переделать. Поэтому важность первоначального этапа часто бывает недооценена.
По поводу своих таблиц, встает вопрос - как документировать и документировать ли вообще свои таблицы в проекте. Т.к. при разработке, как ни крути, а нужно ориентироваться на широкий круг разработчиков (и это всегда надо учитывать при проектирование, ведь это одно из того, за что клиенты любят битрикс), которые смогут в дальнейшем поддерживать и развивать проект. Самое очевидное - это комментирования в коде, но это может вызвать дальнейшее дублирование таблиц, т.к. элементарно - не дошел разработчик до того заветного result_modifier.php и не прочитал заботливо оставленные комментарии. Это конечно менее страшно, чем тысячи строк в множественном свойстве, в карточке товара, но мне не дает с чистой совестью использовать свои таблицы.
Метод с отдельным инфоблоком под ip адреса, интереснее звучит, он и в админке виден, и назвать его можно понятно и по русски, и даже описание прикрутить. Но пока не уверен в сильном выйгрыше. Ведь в итоге это так же превратится либо в длинные списки, либо опять в множественные строки? Единственное гетлистом будет проще выбирать т.к. избыточность возвращенных данных будет сведена к минимуму, в связи с отсуствием полей и свойств элемента за который идет голосование? На досуге попробую протестировать, померить
Полезный пост, на самом деле тема проектирования многими игнорируется и не дооценивается. Бывает разработчик знает, что делает какое-либо API, но не понимает, в каком случае и как лучше использовать. Было бы интересно посмотреть подборку с реальными случаями использования API \ орагнизайцией инфоблоков \ создания своих таблиц и т.д. в стиле "как не надо делать", с комментариями, разъяснениями и правильным подходом Или даже включение такого в справку %)
в стиле "как не надо делать"
Однако можно сколько угодно точить и оптимизировать код, доводя его до совершенства, протестировать на разных серверах с различными условиями, сдать проект, а потом выяснить, что из-за кривых рук пользователя всё "отвалилось" и не работает вообще.
(простейший пример: есть news.list на главной и dews.detail на внутренней - добавление новости, казалось бы, элементарная задача... Но пользователь вместо того, чтобы заполнить детальное описание, редактирует страницу detail.php, предварительно удалив оттуда компонент, а потом жалуется, что все новости с главной ведут на одну детальную новость.)
Поэтому я бы добавил к статье фразу "Не забывайте о кривых руках отдельно взятых пользователей" )
Если у пользователя уже есть сайт, а вы делаете доработки, то тут уже сложнее. Тут остается либо обучать пользователя лучше, записывая ему видеоролик как добавлять новости, либо опять-таки завести ему еще одного пользователя, с другой группой, и убедить пользоваться им.
И третий хардкорный вариант, если пользователь не перестает портить страницы - затащить все страницы в header.php
В любом случаи это вопрос, решаемый по разному в каждом конкретном случаи, так же как и написание или кастомизация модулей/расширений.
Никто из клиентов сейчас не готов к такой схеме при разработке магазина, да и неправильно это. Все характеристики товара должны выводится единообразно, а не отдельно — часть в описании, а часть из свойств. Также важен вопрос заполнения — забивая характеристики в описания:
- будут возникать ошибки
- увеличивается трудоемкость заполнения
- исключаем возможность выгрузки этих характеристик из 1С
Вообще тема характеристик наболевшая. Если под небольшой магазин свойства инфоблоков подходят для хранения характеристик товаров, то при дальнейшем росте уже требуется группировать характеристики (например, для ноутбуков, где характеристик много), давать им поясненяющий текст, управлять тем, какие характеристики будут отображаться в фильтрах разделов товаров. И вот тут уже требуется другое решение, а переход на это решение становится трудоемким.Кто-то фильтрует телефоны по ширине?
Как раз вы привели очень удачный пример.
Единое свойство:
- Высота: 0,3-1,7 см
- Ширина: 30 см
- Глубина: 19,2 см
- Вес: 1,08 кг
Модель 13,3″Не надо заводить для этого 5 свойтв: "высота от", "высота до", "ширина", "глубина", "вес".
Другой причиной чрезмерного обилия свойств может быть объединение
разного рода товаров в одном инфоблоке. Каждый товар добавляет свои
характеристики. Выносите такие товары в отдельные инфоблоки.
Вот на днях через ошибку в своём коде выяснил следующий факт: используя API торговых предложений (SKU), на них невозможно наложить фильтр (в версии 11.0.12, если это имеет значение) .
И если нужны только торговые предложения, скажем, синего цвета, то их придётся отсеивать в result_modifier.
Если по старым методам наоборот, добавляли последними аргументами $arFilter и/или $arSelect, то тут почему-то вернулись к началу.
Характеристики должны оставаться характеристиками, а не подгоняться под CMS.
Взять мой пример выше: контенщику будет проще, очевидно, скопировать из источника текст (или набить): 100x20x60, чем вписывать отдельно эти цифири в разные поля.
Михаил, то что я здесь пишу, не надо воспринимать как догму. Это просто советы. Если в вашей ситуации иное решение вы находите более оптимальным, используйте его и, возможно, будете правы.
Возможно, в будущем модуль будет доработан автором так, что можно будет выделить, т.е. скопировать из таблицы нужную колонку или строку в отдельное своё свойство в инфоблоке для возможности фильтрации.
пример: в тз импорт в 2000 товаров, проходит две недели после сданного проекта и в гарантийный период клиент пытается запихнуть 20000 товаров. а импорт спроектирован без шагов и с небольшим запасом по макс_тайм выполнения пхп.
конечно импорта не работает, заказчик в недоумении.
что делать? планировать на 13000 ? не все заказчики потянут бюджет на проектирование и тестирование каждой функции сайта, поэтому я считаю что эти грабли были и будут всегда и предугадать можно только имея резиновый бюджет на разработку.