保存多语言数据的最佳数据库结构是什么?
可能的重复:
多语言数据库架构
以下是一个示例:
[ 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)
问题:很难吗?
Possible Duplicate:
Schema for a multilanguage database
Here's an example:
[ 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)
The problem: every new language will need modify the table structure.
Here's another example:
[ products-en_us ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
[ products-es_es ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
The problem: every new language will need the creation of new tables and the "price" field is duplicated in every table.
Here's another example:
[ 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)
The problem: hard?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
与方法 3 类似:
因此,对于每个表,创建另一个表(在我的例子中带有“_t”后缀)来保存翻译后的字段。
当您
SELECT * FROM products
时,只需... LEFT JOIN products_t ON products_t.id = products.id AND products_t.language = CURRENT_LANGUAGE
。没那么难,而且可以让你远离头痛。
Similar to method 3:
So for each table, make another table (in my case with "_t" suffix) which holds the translated fields.
When you
SELECT * FROM products
, simply... LEFT JOIN products_t ON products_t.id = products.id AND products_t.language = CURRENT_LANGUAGE
.Not that hard, and keeps you free from headaches.
你的第三个例子实际上是通常解决问题的方式。很难,但可行。
从翻译表中删除对产品的引用,并将对翻译的引用放在您需要的地方(反之亦然)。
作为一种替代方案(不是特别好的选择),您可以拥有一个字段并将所有翻译合并在一起(例如,作为 XML)。
Your third example is actually the way the problem is usually solved. Hard, but doable.
Remove the reference to product from the translation table and put a reference to translation where you need it (the other way around).
As an alternative (not especially a good one) you can have one single field and keep all translations there merged together (as XML, for example).
为了减少 JOIN 的数量,您可以将已翻译和未翻译的内容分开保存在 2 个单独的表中:
In order to reduce the number of JOIN's, you could keep separate the translated and non translated in 2 separate tables :
在我的 $DAYJOB 中,我们使用 gettext 来表示 I18N。我编写了一个插件 xgettext.pl 从数据库表中提取所有英文文本并将它们添加到主 messages.pot 中。
它工作得很好 - 翻译人员在翻译时只处理一个文件 - po 文件。进行翻译时无需修改数据库条目。
At my $DAYJOB we use gettext for I18N. I wrote a plugin to xgettext.pl that extracts all English text from the database tables and add them to the master messages.pot.
It works very well - translators deal with only one file when doing translation - the po file. There's no fiddling with database entries when doing translations.
[语言]
id(整数PK)
code (varchar)
我实际上使用了这种方法,但就我而言,它不是从产品的角度来看,对于我的CMS中的各个页面来说,这种工作相当不错。
如果您有很多产品,那么用 5 或 6 种语言更新单个产品可能会很麻烦……但这是一个布局问题。
[languages]
id (int PK)
code (varchar)
I actually use this method, but in my case, it's not in a product point of view, for the various pages in my CMS, this work's quite well.
If you have a lot of products it might be a headache to update a single one in 5 or 6 languages... but it's a question of working the layout.
那么第四个解决方案呢?
*Translation_of* 是它本身的FK。添加默认语言时,*translation_of* 设置为 Null。但是,当您添加第二语言时,*translation_of* 会采用主要产品语言 ID。
在这种情况下,我们获得 id 为 1 的产品的所有翻译。
我们仅获得波兰语翻译的产品。没有第二个表和联接。
What about fourth solution?
*Translation_of* is FK of it self. When You add default language *translation_of* is set to Null. But when you add second language *translation_of* takes primary produkt language id.
In that case we get all translations for product with id is 1.
We get only product in Polish translation. Without second table and JOINS.
具有多对多的关系。
您有数据表、语言表和 data_language 表。
在 data_language 表中你有
我认为这可能最适合您。
Have many to many relationship.
You have your data table, languages table and a data_language table.
In the data_language table you have
I think that might work best for your.
我们将这个概念用于我们的网站(每天 60 万次浏览)并且(也许令人惊讶)它确实有效。当然还有缓存和查询优化。
We use this concept for our webiste (600k views per day) and (maybe surprisingly) it works. Sure along with caching and query optimalization.