创建多语言数据库的最佳方法是什么?为每个表创建本地化表使设计和查询变得复杂,在其他情况下为每种语言添加列很简单但不动态,请帮助我理解什么是企业应用程序的最佳选择
答案 0 :(得分:192)
我们所做的是为每个多语言对象创建两个表。
E.g。第一个表只包含与语言无关的数据(主键等),第二个表包含每种语言一条记录,包含本地化数据和语言的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,了解有关用于将多语言数据加载到应用程序中的实现的一些其他信息。
答案 1 :(得分:14)
我推荐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");
我相信你可以做得更好。
关键是要以统一的方式命名您的表格和字段。
答案 2 :(得分:13)
我发现这种方法对我有用:
Product ProductDetail Country ========= ================== ========= ProductId ProductDetailId CountryId - etc - ProductId CountryName CountryId Language ProductName - etc - ProductDescription - etc -
ProductDetail表包含您要支持的语言的所有翻译(对于产品名称,描述等)。根据您的应用程序的要求,您可能希望将Country表分解为使用区域语言。
答案 3 :(得分:8)
我正在使用下一种方法:
ProductID OrderID,...
ProductID标题名称LanguageID
LanguageID名称文化,....
答案 4 :(得分:2)
Martin的解决方案与我的解决方案非常相似,但是如果找不到所需的翻译,您将如何处理默认描述?
对于每个字段,是否需要IFNULL()和另一个SELECT语句?
默认转换将存储在同一个表中,其中像“isDefault”这样的标志表示如果找不到当前语言,则该描述是默认描述。