Постановка задачи
Весной 2020-го года мы получили заказ на разработку мультиязычного b2b интернет-магазина для крупного бренда. Целевая аудитория: несколько тысяч дилеров из России, Европы и США. У всех наших проектов есть изюминка, из-за которой пришли именно к нам. Этот проект выделялся хранением данных: товары (картинки, описания, переводы) в postgre, цены и остатки — в нетиповой конфигурации 1С.
Проект масштабный, разработка все еще идет, но архитектура уже определена. В качестве базы выбрали тиражное решение, чтобы сконцентрироваться на нетиповом обмене, архитектуре и получить наглядный результат как можно скорее. В этой статье мы расскажем, как считаем правильным с технической стороны разрабатывать такой мультиязычный сайт с нестандартной учетной системой.
Архитектура
От postgre и нетиповой 1С избавиться на первом этапе не представляется возможным, в первые годы жизни сайта они точно останутся. Но нужно предусмотреть копирование всех данных из postgre в сайт на Битриксе (который на mysql), чтобы в дальнейшем безболезненно отказаться от старой базы.
Как хранятся товары
В БД postgre хранится вся информация о товарах: название, описание, свойства, фотографии (каждый текст, каждый файл в 10-ти вариантах: на популярных европейских языках).
БД postgre устроена иначе, чем любимая Битриксом mysql (речь про допустимое количество колонок в таблице). Сделать копию данных 1 к 1 на новом сайте не получилось, пришлось трансформировать (почти транспонировать) данные.
Было
Article |
NAME_EN |
NAME_FR |
NAME_IT |
Еще ~100 колонок |
150 |
Binoculars Praktica 10x25 WA |
Jumelles Praktica 10x25 WA |
Binocolo Praktica 10x25 WA |
... |
151 |
Discovery Sky Trip ST80 Telescope |
Discovery Sky Trip ST80 Télescope |
Discovery Sky Trip ST80 Telescopio |
... |
Стало
Article |
LANG |
NAME |
Еще ~10 колонок |
150 |
EN |
Binoculars Praktica 10x25 WA |
... |
150 |
FR |
Jumelles Praktica 10x25 WA |
... |
150 |
IT |
Binocolo Praktica 10x25 WA |
... |
151 |
EN |
Discovery Sky Trip ST80 Telescope |
... |
151 |
FR |
Discovery Sky Trip ST80 Télescope |
... |
151 |
IT |
Discovery Sky Trip ST80 Telescopio |
... |
Так как структура всех подобных таблиц в postgre была идентичной, удалось сделать единый механизм импорта с простыми настройками: из какой таблицы postgre взять данные, в какой Hl-блок сложить и сопоставить поля. Так мы смогли синхронизировать 24 таблицы.
Как хранятся цены
У заказчика сложная система ценообразования: для основных стран Европы есть до 4-х цен, как с НДС, так и без. Всего насчитывается 57 типов цен и все они используются, каждая для своей группы клиентов. Каждый дилер покупает товар по одной из этих цен. По какой именно — решает менеджер и фиксирует в 1С, в зависимости от страны дилера и его объема закупок.
Как данные попадают на сайт
Для 2-ух источников данных (postgre, 1C) разработали 2 с половиной механизма обмена.
Каждый день по расписанию сайт «ходит» в postgre по SQL-соединению и синхронизирует данные в своих HL-блоках
По расписанию 1С присылает на сайт через REST API данные каталога, дилеров, склады (пореже), цены и остатки (почаще). При этом сразу создаются неактивные товары без фото, без описания и свойств, так как в 1С этого нет.
Постоянно работающий агент на сайте следит за товарами. Он их “обогащает” переводами, фотографиями, свойствами из HL-блоков и “включает”.
Преимущества такого подхода:
База переводов в понятном виде хранится на сайте в стандартном табличном интерфейсе HL-блоков. Когда понадобится — сделаем более удобный интерфейс и отключим postgre.
1С “знает” что происходит на сайте. Запросы к REST API сайта синхронные, завершаются ответом, что было успешно импортировано, а что нет.
Сразу после выгрузки на сайте создается “скелет” каталога — настоящие разделы и “пустые” товары (без фото, текстов — только служебные названия, цены и остатки).
В течение нескольких минут у каждого “пустого” товара заполняются поля на нужном языке, товар “включается” и его уже можно покупать. Проблем с кешем это не создает, так как такие изменения происходят редко и массово.
Как организована мультиязычность
Мы выбрали “хитрый” способ: копипаст с автоматизацией. У товаров в базе заказчика всегда есть перевод хотя бы на английский, и если нужного языка нет — берем его. Когда проблему замечает контент-менеджер, то исправляет в postgre, и данные постепенно мигрируют в публичный каталог, чтобы новый перевод начал радовать глаз иностранного посетителя.
Много было споров по поводу архитектуры каталога — очень хотелось сделать 1 каталог, и все к этому шло. Проблему с языковыми версиями можно было бы решить, напрямую используя для вывода HL-блоки с переводами. Это бы создало предсказуемые проблемы с поиском и генерацией фидов, которые мы знали, как решать.
Но для разных стран заказчику, по соображениям маркетинга, нужны были разные деревья разделов, разный их состав и даже разная сортировка! Так что на свет появилось такое соответствие: 1 язык -> 1 сайт (в терминах Битрикса) -> 1 каталог товаров с SKU.
А где же результат увидеть?
После 2-ой итерации в конце 2020-го, когда техническая сторона была готова, решили все таки сделать собственный дизайн для сайта. Следующая остановка была летом 2021-го года, тогда мы начали тестирование на реальных дилерах.
Этот проект отлично демонстрирует, какие задачи мы можем и хотим решать: веб-интеграцию любых систем с 1С и сайтом. Продолжение в следующей статье.
Автор: Анатолий Ерофеев.
Комментарии (5)
SbWereWolf
22.11.2021 18:22Для переводов очевидно использовать json, нет ? Или mysql не умеет json колонки ?
Или переводы на каждый язык это всё равно отдельная запись HL-блока ?
Второе забавное. На колонку можно навешать своё правило сортировки (например считать что "е" и "ё" равны, или считать, что "е" меньше "ё"). В postgre, я думаю так и сделано. Но когда вы все переводы переносите в одну колонку, в этот момент вы теряете возможность сортировки строк с учетом языковых особенностей.
С другой стороны сортировка по названию наверное не принципиальна.
И последний вопрос, правильная архитектура в контексте Битрикса ?
stepan_ovchinnikov Автор
23.11.2021 08:381 - json в mysql в 8 версии только. с таблицами/префиксами/id языка проблем особых нет
2 - либо запись, либо колонка.
3 - про сортировку интересная мысль, спасибо
ну битрикс тут немного сбоку. там есть свои заготовки для мультиязычности, но они не решают задачу в целом. так что на мой взгляд архитектура в целом оправданна
AnnaVera
Большое спасибо за вашу статью, я махровый новичок, и сейчас впервые проектирую двуязычную базу данных. Правильно ли я понимаю, что мы добавлением колонок для ещё одного языка уходим от третьей нормальной формы, но так удобнее и эффективнее, чем плодить таблицы под каждый язык? И по факту для каждого отдельно взятого языка у нас как раз и получится 3nf?
stepan_ovchinnikov Автор
вы верно задаете вопрос
тут масса вопросов помимо БД. есть еще организационные сложности
да, копирование полей и таблиц это денормализация, но это по факту оказывается наименьшим злом при реальной разработке
в моей старой статье 14 года все вопросы, в том числе структуры БД, рассмотрены
почитайте -- давайте обсудим https://www.intervolga.ru/blog/projects/bitrix-multylanguage-site/