Моделирование баз данных для международных и многоязычных целей

Мне нужно создать крупномасштабную модель БД для веб-приложения, которое будет многоязычным.

Одно сомнение, что я каждый раз, когда я думаю о том, как это сделать, - это то, как я могу разрешить несколько переводов для поля. Пример.

Таблица уровней языка, которую администраторы могут редактировать из бэкэнд, может иметь несколько элементов, таких как: базовый, продвинутый, свободно, маттер... В ближайшем будущем, вероятно, это будет еще один тип. Администратор переходит на бэкэнд и добавляет новый уровень, он сортирует его в правильном положении.. но как я обрабатываю все переводы для конечных пользователей?

Еще одна проблема с интернационализацией базы данных состоит в том, что, вероятно, для изучения пользователей могут отличаться от США до Великобритании до DE... в каждой стране они будут иметь свои уровни (вероятно, это будет эквивалентно другому, но, наконец, другому). А как насчет выставления счетов?

Как вы моделируете это в большом масштабе?

Ответ 1

Вот как я буду создавать базу данных:

Data model

Визуализация Конструктор конструктора БД

Таблица i18n содержит только PK, так что любая таблица просто должна ссылаться на эту PK для интернационализации поля. Затем таблица translation отвечает за связывание этого общего идентификатора с правильным списком переводов.

locale.id_locale - это VARCHAR(5) для управления как en, так и en_US синтаксиса ISO.

currency.id_currency является CHAR(3) для управления синтаксисом ISO 4217.

Вы можете найти два примера: page и newsletter. Оба этих администратора, которым управляют, должны интернационализировать свои поля, соответственно title/description и subject/content.

Вот пример запроса:

select
  t_subject.tx_translation as subject,
  t_content.tx_translation as content

from newsletter n

-- join for subject
inner join translation t_subject
  on t_subject.id_i18n = n.i18n_subject

-- join for content
inner join translation t_content
  on t_content.id_i18n = n.i18n_content

inner join locale l

  -- condition for subject
  on l.id_locale = t_subject.id_locale

  -- condition for content
  and l.id_locale = t_content.id_locale

-- locale condition
where l.id_locale = 'en_GB'

  -- other conditions
  and n.id_newsletter = 1

Обратите внимание, что это нормализованная модель данных. Если у вас огромный набор данных, возможно, вы могли бы подумать о денормализации его для оптимизации ваших запросов. Вы также можете играть с индексами для повышения производительности запросов (в некоторых БД внешние ключи автоматически индексируются, например MySQL/InnoDB).

Ответ 2

Некоторые предыдущие вопросы StackOverflow по этой теме:

Некоторые полезные внешние ресурсы:

Наилучший подход часто заключается в том, что для каждой существующей таблицы создается новая таблица, в которую перемещаются текстовые элементы; PK новой таблицы - это PK старой таблицы вместе с языком.

В вашем случае:

  • Таблица уровней языка, которую администраторы могут редактировать из бэкэнд, может иметь несколько элементов, таких как: базовый, продвинутый, свободно, маттер... В ближайшем будущем, вероятно, это будет еще один тип. Администратор переходит на бэкэнд и добавляет новый уровень, он сортирует его в правильном положении.. но как я обрабатываю все переводы для конечных пользователей?

    Ваша существующая таблица, вероятно, выглядит примерно так:

    +----+-------+---------+
    | id | price | type    |
    +----+-------+---------+
    |  1 |   299 | basic   |
    |  2 |   299 | advance |
    |  3 |   399 | fluent  |
    |  4 |     0 | mattern |
    +----+-------+---------+
    

    Затем он становится двумя таблицами:

    +----+-------+   +----+------+-------------+
    | id | price |   | id | lang | type        |
    +----+-------+   +----+------+-------------+
    |  1 |   299 |   |  1 | en   | basic       |
    |  2 |   299 |   |  2 | en   | advance     |
    |  3 |   399 |   |  3 | en   | fluent      |
    |  4 |     0 |   |  4 | en   | mattern     |
    +----+-------+   |  1 | fr   | élémentaire |
                     |  2 | fr   | avance      |
                     |  3 | fr   | couramment  |
                     :    :      :             :
                     +----+------+-------------+
    
  • Еще одна проблема с интернационализацией базы данных заключается в том, что, вероятно, для изучения пользователей могут отличаться от США до Великобритании до DE... в каждой стране они будут иметь свои уровни (вероятно, это будет эквивалентно другому, но, наконец, другому). А как насчет выставления счетов?

    Вся локализация может происходить с помощью аналогичного подхода. Вместо того, чтобы просто перемещать текстовые поля в новую таблицу, вы можете перемещать любые локализованные поля - только те, которые являются общими для всех локалей, останутся в исходной таблице.