创建多语言数据库的最佳方法是什么?为每个表创建本地化表会使设计和查询变得复杂,在其他情况下,为每种语言添加列很简单但不是动态的,请帮助我了解什么是企业应用程序的最佳选择
创建多语言数据库的最佳方法是什么?为每个表创建本地化表会使设计和查询变得复杂,在其他情况下,为每种语言添加列很简单但不是动态的,请帮助我了解什么是企业应用程序的最佳选择
Answers:
我们要做的是为每个多语言对象创建两个表。
例如,第一个表仅包含与语言无关的数据(主键等),第二个表包含每种语言的一条记录,其中包含本地化数据以及该语言的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):请查看此答案,以获取有关用于将多语言数据加载到应用程序中的实现的其他信息。
id
:D的列。为了解释,每个id
代表的含义,你可以从任何语言的关系表连接的话,那么你会得到两个表,meaning
(ID)和word
(ID,meaning_id)时,id
在word
表中表示单词标识,id
在meaning
代表具有普遍意义。
我推荐马丁发表的答案。
但是您似乎担心查询变得过于复杂:
为每个表创建本地化表会使设计和查询变得复杂...
因此,您可能会想,而不是像这样编写简单的查询:
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");
而且我相信您可以做得更好。
关键是要以统一的方式命名表和字段。
我发现这种方法适用于我:
产品产品详细国家 =================================== ProductId ProductDetailId CountryId -等-ProductId国家/地区名称 CountryId语言 产品名称-等- 产品描述 -等-
ProductDetail表包含您要支持的语言的所有翻译(用于产品名称,说明等)。根据您应用程序的要求,您可能希望将“国家/地区”表细分为也使用区域语言。
Martin的解决方案与我的解决方案非常相似,但是如果找不到所需的翻译,您将如何处理默认描述?
每个字段都需要IFNULL()和另一个SELECT语句吗?
默认翻译将存储在同一表中,其中的标记(如“ isDefault”)表示如果当前语言没有找到描述,则描述为默认描述。