Sergei_Erjemin
@Sergei_Erjemin
Улыбайся, будь самураем...

Многоязычный сайт… не блог… как?

Как сделать структуру БД многоязычного сайта? (1) Предполагается много связанных таблиц: тарифы, уровни доступа, названия объектов, классификаторы объектов и пр. (2) И есть общая для всех языков графическая контентная часть (графических картинок-диаграмм), где язык не важен (картинка — есть картинка… какой там язык). (3) И есть немного текстового контента «а ля» блог.


Как делать многоязычным блог более менее понятно. Делаем поле с признак языка, и формирование ленты на нужным языке делаем через этот признак.


Делать многоязычным контентно-графическую часть не нужно.


А как сделать многоязыковыми таблицы связей и признаков? В них заложены признаки состояния объектов, классификаторы, описание классов, уровни доступа, биллинг, состояние аккаунтов и прочее, прочее, прочее?.. Но во всех этих таблицах связей-признаков, есть поля описательного характера (например, название типа аккаунтов, или описание класса объекта). И эти описательные поля тоже надо бы сделать многоязычным. Число языков — произвольное (но конечно).


Первой приходит идея — сделать отдельные поля для каждого языка. Но такая схема не расширяема. Т.е. если появится новый язык, придется создавать новые поля (а языков может появится много). На уровне существующих приложения появление новых полей ничего сильно не изменит. Но зато придется писать новые приложения для каждого языка (впрочем, если поля называть умно, то можно просто на уровне приложения «вычислять» какие поля дергать для какого языка.


Вторая идея — сделать отдельные таблицы с описательными характеристиками для каждой таблицы связей, и связать эту таблицу через многое-к-одному с таблицей языков и собственно связей. Все красиво, но структура БД усложняется и может начать тормозить. Теперь при формировании запросов типа JOIN придется сливать вместе больше таблиц (на две дольше в каждый запрос), общее число запросов увеличится, а это может оказаться чревато.


Третья идея — писать в описательные поля на некотором языке разметки и разбирать эту разметку на уровне приложения. Например, описание типов аккаунта будет "[ru::Золотой][en::Gold][jp::ゴールド]"… Плюсы очевидны, но может начать тормозить приложение. Ведь некоторые описательные поля реально большие (например, описание прав и возможностей доступных обладателям «золотого» аккаунта). К тому же это потребует ВСЕ описательные поля сделать избыточной или плавающей длинны, а это замедляет работу СУБД…


Есть ли еще идеи? Может есть традиционные приемы разрешения многоязычности опробованные на CMS?
  • Вопрос задан
  • 4990 просмотров
Решения вопроса 1
alekciy
@alekciy
Вёбных дел мастер
Не понимаю, зачем все так усложнять, когда все укладывается в простую схему. Весь контент сайта условно можно разделить на 3 части:
1) редко меняющиеся данные (они обычно зашиты в файла шаблона);
2) часто меняющие данные либо контент генерируемый пользователями/администраторами/модераторами;
3) бинарные данные в духе картинок, прикрепляемых файлов.

Вся статика находится в папке skin/имя_скина/цветовая_схема/язык (например, /skin/modern/red/ru, у меня по умолчанию /skin/default/default/ru), в базе любой текстовой контент требующий перевода имеет столбцы под каждый требуемый целевой язык. Это могут быть столбцы с постфиксом оригинальное_имя_язык (к примеру, topic_content, topic_content_ru) для mysql или же наследование таблиц из postgresql.

Реализация:
1) вся текстовая информация сосредотачивается в файлах шаблона с использованием gettext-а.
2) постфиксные столбцы во всех таблицах.
3) статические картинки связанные со скином распределены по языковым папкам, адреса же до динамически добавляемых картинок хранятся в базе и при запросе согласно п.2 получаем адрес до нужной языковой картинки.

Единственная трудность с которой тут можно столкнуться, это gettext и переводы требующие контекста. Поскольку переводчик на руки получает po файл, то он не знает, на какой странице сайта используется то или иное слово и какой у него контекст. Но это не очень частый случай и просто требует привлечение к работе разработчика.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@CAMOKPYT
Вынесите всё связанное в переводом во фронтэнд
Ответ написан
@edogs
«Первая идея» — вполне себе расширяема, поля добавляются спокойно, выбор грамотного именования позволит все сделать на автомате. Плюс для языков можно сделать отдельную таблицу, что бы не трогать основные (но при этом класть все языки в одну строку).

«Вторая идея» — хороша в плане «сделать таблицы», но можно не усложнять ее «джоинами» (большого усложнения в прямых выборках нет, но тем не менее)… Джоины в основном нужны, когда инфа из джоинящейся таблицы «нужна прямо сейчас». В случае с языками Вам достаточно в течении приложения просто записывать в массив языковые ИД для джоина (вместо джоина языковой таблицы по ним), а потом в конце приложения сделать запрос в таблицу вытаскивая сразу все языковые переменные по ИД из этого массива и подставляя их в шаблон.

Что касается картинок, не будьте так однозначны. Они тоже бывают многоязычные, например та же инфографика или кнопки.
Ответ написан
Комментировать
@6uxou
Просто вынесите все «переводимые» вещи в отдельные таблицы с полем языка. Скажем если это будет «блог» и его контент должен быть переводимым, то будет 2 таблицы: Заголовок, Контент. У каждой таблицы будет поле языка (language = en/ru/de/jp). Потом соответственно делайте выборку по ним.

p.s.: Так реализованы мультиязычные контенты в Drupal CMS. Посмотрите детально как они там это сделали.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы