Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 多语言数据库设计的最佳实践是什么?_Sql_Database_Database Design - Fatal编程技术网

Sql 多语言数据库设计的最佳实践是什么?

Sql 多语言数据库设计的最佳实践是什么?,sql,database,database-design,Sql,Database,Database Design,创建多语言数据库的最佳方法是什么?为每个表创建本地化表会使设计和查询变得复杂,在另一种情况下,为每种语言添加列很简单,但不是动态的,请帮助我了解企业应用程序的最佳选择是什么,我们要做的是为每个多语言对象创建两个表 例如,第一个表仅包含与语言无关的数据主键等,第二个表包含每种语言的一条记录,其中包含本地化数据和该语言的ISO代码 在某些情况下,我们会添加一个DefaultLanguage字段,这样,如果指定语言没有可用的本地化数据,我们就可以回到该语言 例如: Table "Product": -

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

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

我发现这种方法对我很有效:

Product ProductDetail Country ========= ================== ========= ProductId ProductDetailId CountryId - etc - ProductId CountryName CountryId Language ProductName - etc - ProductDescription - etc -
ProductDetail表包含产品名称、说明等的所有翻译。。使用您想要支持的语言。根据应用程序的要求,您可能希望将国家/地区表分解为使用地区语言。

我将使用下一种方法:

产品 ProductID订单ID

产品信息表 ProductID标题名称LanguageID

语言
LanguageID名称区域性

我推荐马丁的答案

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

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

因此,您可能会想,与其编写这样的简单查询,不如:

SELECT price, name, description FROM Products WHERE price < 100
db.setLocale("en");
db.query("SELECT p.price, _(p.name), _(p.description)
          FROM _(Products p) 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

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

SELECT price, name, description FROM Products WHERE price < 100
db.setLocale("en");
db.query("SELECT p.price, _(p.name), _(p.description)
          FROM _(Products p) WHERE price < 100");
我相信你可以做得更好


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

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

对于每个字段,是否需要一个IFNULL和另一个SELECT语句


默认翻译将存储在同一个表中,其中类似isDefault的标志指示在当前语言未找到任何描述的情况下,该描述是否为默认描述

另一个问题是,为产品创建一个业务对象?或者创造两个。。。在第一种情况下,使用该项很容易,在第二种情况下,编写CMS很容易,如果唯一的语言中性字段是id,该字段是什么?当插入一行时,如何准确地插入外键引用?有趣的是,我当时正在为一个多语言CMS设计一个数据库方案,我脑子里也有这个问题。在我看到这个答案之前,我选择了这个方法!谢谢你的回答!这里需要注意的一点是,这个表上要么没有PK,要么ID和语言需要是复合PK。或者你需要添加一个ProductTranslationId字段,可能是一个标识。@Luca:我回答了你的问题,展示了我用来加载数据的实现。@AarónGutiérrez好吧,有趣的是,你创建了一个表,其中有一列名为id:D。为了解释,每个id代表一个含义,您可以将来自关系表中任何语言的单词附加到该含义,因此您可以得到两个表,Meansion id和word id,Meansion_id,word表中的id代表word id,含义中的id表示通用的含义。另请参见:我发现这对我很有帮助:我为当前正在进行的项目选择了相同的方法,因为我的不同区域设置包含有关向用户显示的单位系统和度量的非常具体的信息。国家和语言区域设置不同东西。ISO语言代码是自然键,可以消除从语言到国家/地区的不必要连接。@GorrillaApe:如果找不到所需语言,请参阅此答案以获取如何返回默认语言的示例: