什么是保持多语言数据的最佳数据库结构?
可能重复:
多语言数据库的架构
这是一个例子:
[ 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)