Какова лучшая структура базы данных для хранения многоязычных данных? [дубликат]


Возможные Дубликаты:
схема для многоязыковой базы данных

вот пример:

[ products ]
id (INT)
name-en_us (VARCHAR)
name-es_es (VARCHAR)
name-pt_br (VARCHAR)
description-en_us (VARCHAR)
description-es_es (VARCHAR)
description-pt_br (VARCHAR)
price (DECIMAL)

проблема: каждый новый язык должен будет изменить структуру таблицы.

вот еще один пример:

[ products-en_us ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)

[ products-es_es ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)

проблема: каждый новый язык будет нуждаться в создании новых таблиц и поле "Цена" дублируется в каждом стол.

вот еще один пример:

[ languages ]
id (INT)
name (VARCHAR)

[ products ]
id (INT)
price (DECIMAL)

[ translation ]
id (INT, PK)
model (VARCHAR) // product
field (VARCHAR) // name
language_id (INT, FK) 
text (VARCHAR)

проблема: чертовски трудно?

8 53

8 ответов:

ваш третий пример на самом деле так, как проблема обычно решается. Тяжело, но выполнимо.

удалите ссылку на продукт из таблицы перевода и поместите ссылку на перевод, где вам это нужно (наоборот).

[ products ]
id (INT)
price (DECIMAL)
title_translation_id (INT, FK)

[ translation ]
id (INT, PK)
neutral_text (VARCHAR)
-- other properties that may be useful (date, creator etc.)

[ translation_text ]
translation_id (INT, FK)
language_id (INT, FK) 
text (VARCHAR)

в качестве альтернативы (не особенно хороший) вы можете иметь одно поле и сохранить все переводы там объединены вместе (как XML, например).

<translation>
  <en>Supplier</en>
  <de>Lieferant</de>
  <fr>Fournisseur</fr>
</translation>

аналогично методу 3:

[languages]
id (int PK)
code (varchar)

[products]
id (int PK)
neutral_fields (mixed)

[products_t]
id (int FK)
language (int FK)
translated_fields (mixed)
PRIMARY KEY: id,language

поэтому для каждой таблицы сделайте другую таблицу (в моем случае с суффиксом "_t"), которая содержит переведенные поля. Когда ты SELECT * FROM products, просто ... LEFT JOIN products_t ON products_t.id = products.id AND products_t.language = CURRENT_LANGUAGE.

не так сложно, и держит вас от головной боли.

чтобы уменьшить количество соединений, вы можете разделить переведенные и непереведенные в 2 отдельных таблицах:

[ products ]
id (INT)
price (DECIMAL)

[ products_i18n ]
id (INT)
name (VARCHAR)
description (VARCHAR)
lang_code (CHAR(5))

на мой $работа мы используем gettext версии для i18n. Я написал плагин для xgettext.pl, которая извлекает все английские тексты из таблиц базы данных и добавить их в мастер-сообщения.горшок.

Он работает очень хорошо-переводчики имеют дело только с одним файлом при выполнении перевода - файл po. Там нет возиться с записями базы данных при выполнении переводов.

[языки] идентификатор (инт ПК) код (тип varchar)

[products]
id (int PK)
name
price
all other fields of product
id_language ( int FK )

Я на самом деле использую этот метод, но в моем случае, это не с точки зрения продукта, для различных страниц в моей CMS, эта работа довольно хорошо.

Если у вас есть много продуктов, это может быть головная боль, чтобы обновить один из них на 5 или 6 языках... но это вопрос работы макета.

как насчет четвертого решения?

[ products ]
id (INT)
language (VARCHAR 2)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
*translation_of (INT FK)*

* Translation_of* is FK это самостоятельно. При добавлении языка по умолчанию * translation_of * имеет значение Null. Но при добавлении второго языка * translation_of * принимает первичный код языка продукта.

SELECT * FROM products WHERE id = 1 AND translation_of = 1

В этом случае мы получаем все переводы для товара с id 1.

SELECT * FROM products WHERE id = 1 AND translation_of = 1 AND language = 'pl'

мы получаем только продукт в польском переводе. Без второй таблицы и присоединяется.

многие ко многим отношения.

У вас есть таблица данных, таблица языков и таблица data_language.

в таблице data_language у вас есть

id, data_id, language_id

Я думаю, что это может работать лучше для вас.

мы используем эту концепцию для нашего webiste (600k просмотров в день) и (возможно, удивительно) это работает. Конечно, наряду с кэшированием и оптимизацией запросов.

[attribute_names]
id (INT)
name (VARCHAR)

[languages_names]
id (INT)
name (VARCHAR)

[products]
id (INT)
attr_id (INT)
value (MEDIUMTEXT)
lang_id (INT)