什么是保持多语言数据的最佳数据库结构?

可能重复:
多语言数据库的架构

这是一个例子:

[ 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) 

问题是:每一种新语言都需要创build新的表格,“价格”字段在每个表格中都是重复的。

这是另一个例子:

 [ 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) 

问题: fuc * ing很难?

你的第三个例子实际上是通常解决问题的方式。 很难,但可行。

从翻译表中删除对产品的引用,并在需要的地方提供翻译的引用(反过来)。

 [ 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

不那么难,让你摆脱头痛。

为了减lessJOIN的数量,你可以将翻译和非翻译分开在两个单独的表中:

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

在我的$ DAYJOB我们使用gettext为I18N。 我为xgettext.pl编写了一个插件,从数据库表中提取所有英文文本,并将它们添加到主文件messages.pot中。

它工作得很好 – 译员在翻译时只处理一个文件 – po文件。 翻译时没有数据库条目的摆弄。

[语言] id(int PK)代码(varchar)

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

我实际上使用这种方法,但在我的情况下,这不是从产品的angular度来看,对于CMS中的各种页面,这个工作非常好。

如果你有很多产品,用5种或者6种语言更新一个产品可能会让你头痛不已,但这是一个布局工作的问题。

那第四个解决scheme呢?

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

* Translation_of *是FK的自我。 当您添加默认语言时* translation_of *设置为Null。 但是,当你添加第二语言* translate_of *采取主要produkt语言ID。

 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

我认为这可能对你的工作最好。

我们使用这个概念为我们的网站(每天600k的意见),(也许令人惊讶),它的工作原理。 当然还有caching和查询优化。

 [attribute_names] id (INT) name (VARCHAR) [languages_names] id (INT) name (VARCHAR) [products] id (INT) attr_id (INT) value (MEDIUMTEXT) lang_id (INT)