多语言数据库设计的最佳实践是什么?[关闭]


193

创建多语言数据库的最佳方法是什么?为每个表创建本地化表会使设计和查询变得复杂,在其他情况下,为每种语言添加列很简单但不是动态的,请帮助我了解什么是企业应用程序的最佳选择



3
我发现这对我非常有帮助:MySQL中的多语言数据库设计
Siamak A.Motlagh 2014年

Answers:


222

我们要做的是为每个多语言对象创建两个表。

例如,第一个表仅包含与语言无关的数据(主键等),第二个表包含每种语言的一条记录,其中包含本地化数据以及该语言的ISO代码。

在某些情况下,我们会添加一个DefaultLanguage字段,以便在没有针对指定语言的本地化数据时可以回退到该语言。

例:

Table "Product":
----------------
ID                 : int
<any other language-neutral fields>


Table "ProductTranslations"
---------------------------
ID                 : int      (foreign key referencing the Product)
Language           : varchar  (e.g. "en-US", "de-CH")
IsDefault          : bit
ProductDescription : nvarchar
<any other localized data>

使用这种方法,您可以根据需要处理多种语言(而不必为每种新语言添加其他字段)。


更新(2014-12-14):请查看此答案,以获取有关用于将多语言数据加载到应用程序中的实现的其他信息。


14
如果唯一与语言无关的字段是id怎么办?以及插入行时如何精确插入外键引用?
Timo Huovinen

4
有趣的是,我正在为一种多语言CMS设计数据库方案,并且这个问题也浮现在脑海。我选择了这种方法,甚至没有看到这个答案!感谢您的回答!
Patrick Manser

5
这里要注意的一件事是,该表上将没有PK,或者ID和Language必须是复合PK。或者,或者您需要添加一个ProductTranslationId字段,可能作为标识。
Daniel Lorenz 2014年

1
@Luca:我回答了您的问题,显示了我用于加载数据的实施方式。
M4N 2014年

1
@AarónGutiérrez好吧,很有趣的是,您创建了一个表,该表只有一个名为id:D的列。为了解释,每个id代表的含义,你可以从任何语言的关系表连接的话,那么你会得到两个表,meaning(ID)和word(ID,meaning_id)时,idword表中表示单词标识,idmeaning代表具有普遍意义。
Timo Huovinen 18/09/17

18

我推荐马丁发表的答案。

但是您似乎担心查询变得过于复杂:

为每个表创建本地化表会使设计和查询变得复杂...

因此,您可能会想,而不是像这样编写简单的查询:

SELECT price, name, description FROM Products WHERE price < 100

...您将需要开始编写如下查询:

SELECT
  p.price, pt.name, pt.description
FROM
  Products p JOIN ProductTranslations pt
  ON (p.id = pt.id AND pt.lang = "en")
WHERE
  price < 100

不是很漂亮的观点。

但是,您应该开发自己的数据库访问类,而不是手动进行操作,该类将预先解析包含特殊本地化标记的SQL,并将其转换为需要发送到数据库的实际SQL。

使用该系统可能看起来像这样:

db.setLocale("en");
db.query("SELECT p.price, _(p.name), _(p.description)
          FROM _(Products p) WHERE price < 100");

而且我相信您可以做得更好。

关键是要以统一的方式命名表和字段。


另一个问题是,为产品创建一个业务对象?或创建两个...第一种情况下,很容易使用该项目,第二种情况下易于编写CMS
Arsen Mkrtchyan,2009年

14

我发现这种方法适用于我:

产品产品详细国家
===================================
ProductId ProductDetailId CountryId
-等-ProductId国家/地区名称
            CountryId语言
            产品名称-等-
            产品描述
            -等-

ProductDetail表包含您要支持的语言的所有翻译(用于产品名称,说明等)。根据您应用程序的要求,您可能希望将“国家/地区”表细分为也使用区域语言。


我为当前正在研究的项目选择了相同的方法,因为我的不同语言环境包含有关单元系统和要显示给用户的度量的非常具体的信息。
califrench

8
国家和语言(语言环境)是不同的东西。而且ISO语言代码是自然键,您可以消除从lang到国家/地区的不必要的连接。
gotnkoa

10

我正在使用下一种方法:

产品

产品ID订单ID,...

产品信息

产品ID标题名称LanguageID

语言

LanguageID名称文化,....


2

Martin的解决方案与我的解决方案非常相似,但是如果找不到所需的翻译,您将如何处理默认描述?

每个字段都需要IFNULL()和另一个SELECT语句吗?

默认翻译将存储在同一表中,其中的标记(如“ isDefault”)表示如果当前语言没有找到描述,则描述为默认描述。


1
@GorrillaApe:如果未找到所需的语言,请参见以下答案的示例以了解如何回退到默认语言:stackoverflow.com/a/27474681/19635
M4N
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.