【问题标题】:What are best practices for multi-language database design? [closed]多语言数据库设计的最佳实践是什么? [关闭]
【发布时间】:2010-10-30 02:06:39
【问题描述】:

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

【问题讨论】:

标签: sql database database-design


【解决方案1】:

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

例如第一个表仅包含与语言无关的数据(主键等),第二个表包含每种语言的一条记录,包含本地化数据和该语言的 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):请查看 this answer,了解有关用于将多语言数据加载到应用程序中的实现的更多信息。

【讨论】:

  • 如果唯一与语言无关的字段是 id 怎么办?以及在插入行时究竟是如何插入外键引用的?
  • 很有趣,我正在为多语言 CMS 设计一个数据库方案,并且我的脑海中也有这个问题。我什至在看到这个答案之前就选择了这种方法!感谢您的回答!
  • 这里要注意的一点是,要么此表上没有 PK,要么 ID 和 Language 需要是复合 PK。要么,要么你需要添加一个 ProductTranslationId 字段,可能作为一个身份。
  • @Luca:我回答了你的问题,展示了我使用哪些实现来加载数据。
  • @AarónGutiérrez 好吧,有趣的是,您创建了一个表,其中包含一个名为 id :D 的单列。解释一下,每个id 代表一个含义,您可以在关系表中附加来自任何语言的单词,因此您会得到两个表,meaning (id) 和 word (id,meaning_id),id word表中的id代表单词id,meaning中的meaning代表通用的意思。
【解决方案2】:

我推荐 Martin 发布的答案。

但您似乎担心您的查询过于复杂:

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

所以你可能会想,与其编写这样的简单查询:

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
【解决方案3】:

我发现这种方法适合我:

产品 产品详情 国家 ===================================== ProductId ProductDetailId CountryId - 等等 - ProductId CountryName CountryId 语言 产品名称 - 等等 - 产品描述 - 等等 -

ProductDetail 表包含您想要支持的语言的所有翻译(产品名称、描述等)。根据您应用的要求,您可能希望将 Country 表分解为也使用区域语言。

【讨论】:

  • 我为我目前正在从事的项目选择了同样的方法,因为我的不同语言环境包含有关要向用户显示的单位系统和度量的非常具体的信息。
  • 国家和语言(地区)是不同的东西。并且 ISO 语言代码是自然键,您消除了从语言到国家的不必要连接。
【解决方案4】:

我正在使用下一种方法:

产品

ProductID 订单ID,...

产品信息

ProductID 标题名称 LanguageID

语言

LanguageID 名称文化,....

【讨论】:

    【解决方案5】:

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

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

    默认翻译将存储在同一个表中,其中像“isDefault”这样的标志指示该描述是否是默认描述,以防当前语言没有找到。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    相关资源
    最近更新 更多