Які найкращі практики для розробки багатомовних баз даних? [зачинено]


193

Який найкращий спосіб створити багатомовну базу даних? Щоб створити локалізовану таблицю для кожної таблиці, це складання дизайну та запитів, в іншому випадку додати стовпчик для кожної мови просто, але не динамічно, допоможіть мені зрозуміти, що найкраще вибрати для корпоративних програм



3
Я вважаю це дуже корисним для мене: багатомовний дизайн баз даних в MySQL
Siamak A.Motlagh

Відповіді:


223

Ми робимо дві таблиці для кожного багатомовного об'єкта.

Наприклад, перша таблиця містить лише нейтральні щодо мови дані (первинний ключ тощо), а друга таблиця містить один запис на кожну мову, що містить локалізовані дані плюс код ISO мови.

У деяких випадках ми додаємо поле DefaultLanguage, щоб ми могли повернутися до цієї мови, якщо для вказаної мови немає локалізованих даних.

Приклад:

Table "Product":
----------------
ID                 : int
<any other language-neutral fields>


Table "ProductTranslations"
---------------------------
ID                 : int      (foreign key referencing the Product)
Language           : varchar  (e.g. "en-US", "de-CH")
IsDefault          : bit
ProductDescription : nvarchar
<any other localized data>

При такому підході ви можете обробити стільки мов, скільки потрібно (без необхідності додавати додаткові поля для кожної нової мови).


Оновлення (2014-12-14): перегляньте цю відповідь , щоб отримати додаткову інформацію про реалізацію, яка використовується для завантаження багатомовних даних у додаток.


15
що робити, якщо єдиним мовним нейтральним полем є id? і як саме ви вставляєте посилання іноземного ключа, коли вставляєте рядок?
Тімо Хуовінен

4
Смішно, що я розробляв схему бази даних для багатомовної CMS і мав це питання також в голові. Я вибрав такий підхід, перш ніж я навіть не побачив цю відповідь! Дякую за цю відповідь!
Патрік Мансер

5
Тут слід зауважити, що на цій таблиці не повинно бути або ПК, або ID та мова повинні бути складеними ПК. Або це, або вам потрібно додати поле ProductTranslationId, ймовірно, як ідентичність.
Даніель Лоренц

1
@Luca: Я відповів на ваше запитання, показуючи, яку реалізацію я використовую для завантаження даних.
M4N

1
@ AarónGutiérrez Ну, як не дивно, ви створюєте таблицю з одного стовпця під назвою id: D. Для того, щоб пояснити, кожен idпредставляє собою значення , до якого можна прикріпити слова з будь-якої мови в реляційної таблиці, так що ви отримаєте дві таблиці, meaning(Id) і word(ID, meaning_id), то idв wordтаблиці представляє слово ідентифікатор, то idв meaningпредставляє значення, яке є універсальним.
Тімо Хуовінен

18

Рекомендую відповідь, опубліковану Мартіном.

Але ви, мабуть, стурбовані тим, що ваші запити стають занадто складними:

Щоб створити локалізовану таблицю для кожної таблиці, це складний дизайн та запит ...

Тож ви можете думати, що замість того, щоб писати прості запити на зразок цього:

SELECT price, name, description FROM Products WHERE price < 100

... вам слід почати писати такі запити:

SELECT
  p.price, pt.name, pt.description
FROM
  Products p JOIN ProductTranslations pt
  ON (p.id = pt.id AND pt.lang = "en")
WHERE
  price < 100

Не дуже гарна перспектива.

Але замість цього робити це вручну, ви повинні розробити власний клас доступу до бази даних, який попередньо розбирає SQL, який містить вашу спеціальну розмітку локалізації, і перетворює його у фактичний SQL, який вам потрібно буде надіслати до бази даних.

Використання цієї системи може виглядати приблизно так:

db.setLocale("en");
db.query("SELECT p.price, _(p.name), _(p.description)
          FROM _(Products p) WHERE price < 100");

І я впевнений, що ти можеш зробити ще краще, що це.

Головне, щоб ваші таблиці та поля були названі однаково.


інше питання - створити один бізнес-об’єкт для продукту? або створити два ... спочатку легко працювати з цим елементом, у другому легко написати CMS
Arsen Mkrtchyan

14

Я вважаю, що такий тип підходу працює для мене:

Product ProductДетальна країна
========= =============================
ProductId ProductDetailId CountryId
- тощо - ProductId CountryName
            Мова країни Id
            Назва продукту - тощо.
            Опис продукту
            - тощо -

Таблиця ProductDetail містить усі переклади (назви продукту, опис тощо) на мовах, які ви хочете підтримувати. Залежно від вимог вашої програми, ви можете розбити таблицю "Країна" та використовувати регіональні мови.


Я вибрав такий самий підхід для проекту, над яким я зараз працюю, тому що мої різні локалі містять дуже конкретну інформацію про одиничні системи та заходи, які слід відображати користувачам.
каліфрен

8
Країна та мова (місцевості) - це різні речі. І коди мови ISO - це природні ключі, ви усуваєте непотрібне приєднання з мови до країни.
gavenkoa

10

Я використовую наступний підхід:

Товар

ProductID OrderID, ...

ProductInfo

Назва продукту Назва мовиID

Мова

LanguageID Назва культури, ....


2

Рішення Мартіна дуже схоже на моє, проте як би ви обробляли описи за замовчуванням, коли потрібний переклад не знайдено?

Чи потрібно для цього поле IFNULL () та інший вибір SELECT?

Переклад за замовчуванням буде зберігатися в тій самій таблиці, де прапор типу "isDefault" вказує, що цей опис є описом за замовчуванням, якщо в поточній мові не знайдено жодного.


1
@GorrillaApe: см ця відповідь на приклад того, як впасти назад на мову за замовчуванням, якщо потрібна мова не був знайдений: stackoverflow.com/a/27474681/19635
M4N
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.