mysql-保留多语言数据的最佳数据库结构是什么?
可能重复:
多语言数据库的架构
这是一个例子:
[ 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个解决方案
37 votes
与方法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。
没那么难,让您免于头痛。
Gipsy King answered 2020-01-10T23:33:49Z
28 votes
您的第三个示例实际上是通常解决问题的方式。 努力,但可行。
从翻译表中删除对产品的引用,然后将翻译的引用放在您需要的地方(反之亦然)。
[ 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)。
Supplier
Lieferant
Fournisseur
answered 2020-01-10T23:33:20Z
13 votes
为了减少JOIN的数量,您可以在2个单独的表中分别保留已翻译和未翻译的内容:
[ products ]
id (INT)
price (DECIMAL)
[ products_i18n ]
id (INT)
name (VARCHAR)
description (VARCHAR)
lang_code (CHAR(5))
Clément answered 2020-01-10T23:34:09Z
3 votes
在我的$ DAYJOB,我们将gettext用于I18N。 我向xgettext.pl编写了一个插件,该插件从数据库表中提取所有英文文本,并将其添加到主messages.pot中。
它工作得很好-翻译人员在翻译时仅处理一个文件-po文件。 进行翻译时,无需摆弄数据库条目。
holygeek answered 2020-01-10T23:34:34Z
2 votes
[语言] id(int PK) 代码(varchar)
[products]
id (int PK)
name
price
all other fields of product
id_language ( int FK )
我实际上使用了这种方法,但就我而言,这并不是从产品的角度来看的,对于CMS中的各个页面,这项工作都很好。
如果您有很多产品,可能很难用5种或6种语言来更新一个产品……但这是布局设计的问题。
Tio answered 2020-01-10T23:35:03Z
0 votes
那第四种解决方案呢?
[ products ]
id (INT)
language (VARCHAR 2)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
*translation_of (INT FK)*
* Translation_of *是它自身的FK。 添加默认语言时,* translation_of *设置为Null。 但是,当您添加第二种语言时,* translation_of *将使用主要产品语言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'
我们仅提供波兰语翻译产品。 没有第二张桌子和联接。
chf answered 2020-01-10T23:35:37Z
-1 votes
有多对多的关系。
您有数据表,语言表和data_language表。
在data_language表中
id,data_id,language_id
我认为这可能最适合您。
AntonioCS answered 2020-01-10T23:36:14Z
-2 votes
我们将这种概念用于您的网站(每天60万次观看),并且(也许令人惊讶地)有效。 当然可以进行缓存和查询优化。
[attribute_names]
id (INT)
name (VARCHAR)
[languages_names]
id (INT)
name (VARCHAR)
[products]
id (INT)
attr_id (INT)
value (MEDIUMTEXT)
lang_id (INT)
Petr Peller answered 2020-01-10T23:36:34Z