我希望我的数据库支持表格中所有文本值的多语言。
那么最好的方法是什么?。
EDIT1 ::
E.G。
我有这个“人”表:
ID int
FirstName nvarchar(20)
LastName nvarchar(20)
Notes nvarchar(max)
BirthDate date
...........
所以,如果我希望我的程序支持新语言“让我说法语”。
每次添加新语言时都应该添加新列吗? 所以我的“人物”表看起来像这样
ID int
FirstName_en nvarchar(20)
FirstName_fr nvarchar(20)
LastName_en nvarchar(20)
LastName_fr nvarchar(20)
Notes_en nvarchar(max)
Notes_fr nvarchar(max)
BirthDate date
...........
或者我应该为语言添加2个新表,为“Person_Languages”值添加其他表吗?
所以这看起来像: “ 语言 ”表格:
ID int
Lang-symbol nvarchar(4)
“ 人 ”表格:
ID int
BirthDate Date
最后“ Person_Translation ”表:
LangID int
PersonID int
Translation nvarchar(max)
答案 0 :(得分:9)
我必须在问卷数据库中处理这个问题。多个问卷需要用多种语言翻译(英语,日语,中文)。
我们首先确定了将在问卷上打印出来的所有文本列。对于所有这些,我们需要能够存储翻译。对于每个具有需要翻译的文本列的表,我们创建了一个_translations表,其中一个外键指向原始表的主键,一个外键指向我们的语言表,然后是每个文本字段的unicode列。这需要翻译。在这些文本列中,我们将存储我们需要的每种语言的翻译。
所以典型的查询看起来像:
select p.id
, pt.product_name
, pt.product_description
from product p
inner join product_translations pt
on p.id = pt.product_id
and 'fr' = pt.language_code
因此,总是只需要一个额外的连接(对于每个表)来获得翻译。
我应该指出,我们只处理有限数量的表,因此维护一些额外的%_translations表并不是一个大问题。
我们确实考虑过为新语言添加列,但出于各种原因决定反对它。首先,支持的语言数量尚不清楚,但可能是实质性的(10种,20种语言或更多)。结合大多数表至少有3个不同的人类可读列的事实,我们必须添加许多很多文本列,这将导致非常宽的行。所以我们决定不这样做。
我们考虑制作一个大“标签”表的另一种方法,即列:
(table_name ,id_of_table ,column_name ,language_id ,translated_text)
有效地使用一个表来存储数据库中任何位置的所有翻译。我们也反对这一点,因为它会使编写查询变得复杂(因为每个'普通'列将导致转换表中的一行,这将导致将已经很大的转换表多次重复加入普通表(每次一次)翻译专栏)。对于你的示例表,你会得到这样的查询:
select product.id
, product_name.translated_text product_name
, product_description.translated_text product_description
from product p
inner join translations product_name
on p.id = product_name.id
and 'product' = product_name.table_name
and 'product_name' = product_name.column_name
and 'fr' = product_name.language
inner join translations product_description
on p.id = product_name.id
and 'product' = product_description.table_name
and 'product_description' = product_description.column_name
and 'fr' = product_description.language
正如您所看到的,基本上这类似于实体属性值设计,这使得查询变得很麻烦。
最后一种方法的另一个问题是,如果不是不可能的话,对翻译文本强制执行约束(在我们的例子中主要是单一性约束)会很困难。通过单独的翻译表,您可以轻松,干净地克服这些问题。
答案 1 :(得分:2)
我刚刚实施了一些效果很好的东西。
和其他许多人一样,我开始时没有一个干净的名单,并且所有的表格都准备好存储英文文本。
我不是特别乐意将表或列的数量加倍以实现多语言数据库。
我决定利用XML作为将所有翻译存储到单个字段中的方法:
<text>
<translation lang="EN-GB">good day</translation>
<translation lang="FR-FR">bonjour</translation>
</text>
例如,我开始使用只持有英语的表:
ProductId INT
ProductName varchar(200)
ProductDescription varchar(1000)
然后我创建了多语言字段:
ProductId INT
ProductNameTranslation xml
ProductDescriptionTranslation xml
如果您希望能够获得原始字段的只读值,则只需添加一个持久计算列:
ProductId INT
ProductNameTranslation xml
ProductDescriptionTranslation xml
ProductNameDefaultLang = dbo.GetDefaultLanguage(ProductNameTranslation)
ProductDescriptionDefaultLang = dbo.GetDefaultLanguage(ProductDescriptionTranslation)
在业务/数据层中,XML字段将转换为字典类型的业务类,其中key是语言枚举:
ProductName {
get {return this.ProductNameTranslation[selectedLanguage];}
set {...}
}
这种方法让我可以避免完全重新修复数据库。它还意味着与数据库的交互较少,要保存一行而不是一个主行,以及3个转换行。
此外,它避免了必须处理主行没有翻译行的情况的问题
应该注意的是,XML有一个模式和XML索引来提高性能。
如果您希望逐步进行语言转换(即一次一个字段),此方法非常有用。