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

Thi*_*lem 53 mysql database multilingual translation localization

可能重复:
多语言数据库的模式

这是一个例子:

[ 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)
Run Code Online (Sandbox Code Playgroud)

问题是:每种新语言都需要修改表结构.

这是另一个例子:

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

[ products-es_es ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
Run Code Online (Sandbox Code Playgroud)

问题是:每种新语言都需要创建新表,并且"价格"字段在每个表中都是重复的.

这是另一个例子:

[ 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)
Run Code Online (Sandbox Code Playgroud)

问题: fuc*ing hard?

Gip*_*ing 38

与方法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
Run Code Online (Sandbox Code Playgroud)

因此,对于每个表,创建另一个表(在我的情况下带有"_t"后缀),其中包含已翻译的字段.当你SELECT * FROM products,简单... LEFT JOIN products_t ON products_t.id = products.id AND products_t.language = CURRENT_LANGUAGE.

没那么难,让你摆脱头痛.


小智 28

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

从翻译表中删除对产品的引用,并在需要的地方提供翻译参考(反之).

[ 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)
Run Code Online (Sandbox Code Playgroud)

作为替代方案(不是特别好的方法),您可以拥有一个单独的字段,并将所有翻译合并在一起(例如,XML).

<translation>
  <en>Supplier</en>
  <de>Lieferant</de>
  <fr>Fournisseur</fr>
</translation>
Run Code Online (Sandbox Code Playgroud)

  • 如果产品表包含多个翻译字段怎么办?检索产品时,每个翻译字段必须再进行一次连接,这将导致严重的性能问题.插入/更新/删除还有(IMO)额外的复杂性.这样做的唯一优点是表的数量较少.我会选择Gipsy King或Clément提出的方法:我认为这是性能,复杂性和维护问题之间的良好平衡. (11认同)

Clé*_*ent 14

为了减少JOIN的数量,您可以将翻译和非翻译分开保存在2个单独的表中:

[ products ]
id (INT)
price (DECIMAL)

[ products_i18n ]
id (INT)
name (VARCHAR)
description (VARCHAR)
lang_code (CHAR(5))
Run Code Online (Sandbox Code Playgroud)

  • @TiuTalk - 只有一个表格会获得新字段,如果是翻译字段,则进入`products_i18n`,否则进入`products`.这样您就不会复制任何信息. (7认同)