| 
                         之前做的项目涉及到中国大陆和纽伦新港的用户使用,也就需要做成一个多语言的系统,现在总结下其中一些经验和思考。   首先我们需要确认我们要做的系统,多语言到底是要做多少种语言,以后会不会要求增加更多的语言。比如我们做一个给中国大陆和纽伦新港使用的系统,可以确定的语言就是简体中文、繁体中文和英语,而且可以确定以后也不会增加语言。确定以后是否需要增加语言这一点很重要,决定了我们在数据库设计时,是否需要考虑多语上的扩展性。   先说下在数据库设计时,可以有以下方案实现多语:   一、为每个多语字段建立对应语言的字段列。   比如我们有一个客户表,记录了客户Id、客户名称、客户地址、客户电话等,其中客户名称和客户地址是多语的,而且需要支持简体中文、繁体中文和英语,于是我们可以将客户表设计如下:   
这样做的优点是容易理解,容易查询,一个客户实例对应的就是数据库中的一条数据,与普通的非多语数据库无异,而且由于没有形成新的表,所以也不需要额外的Join,所以查询效率很高: 
<pre class="csharpcode">insert <span class="kwrd">into Client <span class="kwrd">values(1,<span class="str">'工商银行',<span class="str">'工商銀行',<span class="str">'ICBC',<span class="str">'中国北京',<span class="str">'中國北京',<span class="str">'China,Beijing',<span class="str">'13811255555'); 
<span class="kwrd">select * 
<span class="kwrd">from Client c 
<span class="kwrd">where c.ClientId=1  
二、建立统一的翻译表,在翻译表中使用多列存储多语言,然后在实体表中外键引用翻译表。 
<pre class="csharpcode"><span class="kwrd">create <span class="kwrd">table <span class="kwrd">Translation 
( 
TranslationId <span class="kwrd">int <span class="kwrd">primary <span class="kwrd">key,TextChs nvarchar(200),TextCht nvarchar(200),TextEng <span class="kwrd">varchar(200),) 
<span class="kwrd">create <span class="kwrd">table Client 
( 
ClientId <span class="kwrd">int <span class="kwrd">primary <span class="kwrd">key,NameTranId <span class="kwrd">int <span class="kwrd">references <span class="kwrd">Translation(TranslationId),AddressTranId <span class="kwrd">int <span class="kwrd">references <span class="kwrd">Translation(TranslationId),TelephoneNumber <span class="kwrd">varchar(200) 
) 
这样要查询数据时,需要将Translation表JOIN2次,获得对应的Name和Address的多语。 
<pre class="csharpcode">insert <span class="kwrd">into <span class="kwrd">Translation <span class="kwrd">values(10,<span class="str">'ICBC'); 
insert <span class="kwrd">into <span class="kwrd">Translation <span class="kwrd">values(20,Beijing'); 
insert <span class="kwrd">into Client <span class="kwrd">values(1,10,20,<span class="str">'13811255555'); 
<span class="kwrd">select c.ClientId,c.TelephoneNumber,tn.TextChs <span class="kwrd">as NameChs,tn.TextCht <span class="kwrd">as NameCht,tn.TextEng <span class="kwrd">as NameEng,ta.TextChs <span class="kwrd">as AddressChs,ta.TextCht <span class="kwrd">as AddressCht,ta.TextEng <span class="kwrd">as AddressEng 
<span class="kwrd">from Client c 
<span class="kwrd">inner <span class="kwrd">join <span class="kwrd">Translation tn 
<span class="kwrd">on c.NameTranId=tn.TranslationId 
<span class="kwrd">inner <span class="kwrd">join <span class="kwrd">Translation ta 
<span class="kwrd">on c.AddressTranId=ta.TranslationIdwhere 
<span class="kwrd">where c.ClientId=1 
以上介绍的方法都是将多语作为列输出,也就是说有多少种语言就会有多少对于的列,不利于语言的增加下面再介绍将语言以数据行的形式保存的设计方法,这种方法可以在后期任意增加语言而不改动数据库Schema. 
三、将每个表中需要多语的字段独立出来,形成一个对应的多语表。 
多语表外键关联原表,每个需要多语的字段在多语表中对应一列,多语表中增加“语言”字段。同样以Client表为例,那么对应的表结构是: 
<pre class="csharpcode"><span class="kwrd">create <span class="kwrd">table Client 
( 
ClientId <span class="kwrd">int <span class="kwrd">primary <span class="kwrd">key,TelephoneNumber <span class="kwrd">varchar(200) 
) 
<span class="kwrd">create <span class="kwrd">table Client_MultiLanguages 
( 
CLId <span class="kwrd">int <span class="kwrd">primary <span class="kwrd">key,ClientId <span class="kwrd">int <span class="kwrd">references Client(ClientId),Name nvarchar(200),Address nvarchar(200),<span class="kwrd">Language <span class="kwrd">char(3) 
) 
这样的优点是便于扩展,在Schema中并没有定义具体的语言,所以如果要增加语言的话,只需要在多语表中增加一行对应的数据即可。查询也相对比较简单,执行要将原表与对应的多语表JOIN,然后跟上具体的语言作为WHERE条件,即可完成对数据的查询,比如要查询Id为1的Client对象的英语实例: 
<pre class="csharpcode">insert <span class="kwrd">into Client <span class="kwrd">values(1,<span class="str">'13811255555'); 
insert <span class="kwrd">into Client_MultiLanguages <span class="kwrd">values(1,1,<span class="str">'CHS'); 
insert <span class="kwrd">into Client_MultiLanguages <span class="kwrd">values(2,<span class="str">'CHT'); 
insert <span class="kwrd">into Client_MultiLanguages <span class="kwrd">values(3,<span class="str">'ENG'); 
<span class="kwrd">select c.*,cm.Name,cm.Address 
<span class="kwrd">from Client c <span class="kwrd">inner <span class="kwrd">join Client_MultiLanguages cm 
<span class="kwrd">on c.ClientId=cm.ClientId 
<span class="kwrd">where c.ClientId=1 <span class="kwrd">and cm.<span class="kwrd">Language=<span class="str">'ENG' 
四、建立统一翻译表和对应的多语表,在每个多语列指向翻译表。 
<pre class="csharpcode"><span class="kwrd">create <span class="kwrd">table <span class="kwrd">Translation 
( 
TranslationId <span class="kwrd">int <span class="kwrd">primary <span class="kwrd">key 
) 
<span class="kwrd">create <span class="kwrd">table Client 
( 
ClientId <span class="kwrd">int <span class="kwrd">primary <span class="kwrd">key,TelephoneNumber <span class="kwrd">varchar(200) 
) 
<span class="kwrd">create <span class="kwrd">table TranslationEntity 
( 
TranslationEntityId <span class="kwrd">int <span class="kwrd">primary <span class="kwrd">key,TranslationId <span class="kwrd">int <span class="kwrd">references <span class="kwrd">Translation(TranslationId),<span class="kwrd">Language <span class="kwrd">char(3),TranslatedText nvarchar(200) 
) 
如果要查询Id为1的Client对应的英语实例,那么脚本为: 
<pre class="csharpcode">insert <span class="kwrd">into <span class="kwrd">Translation <span class="kwrd">values(10); 
insert <span class="kwrd">into <span class="kwrd">Translation <span class="kwrd">values(20); 
insert <span class="kwrd">into Client <span class="kwrd">values(1,<span class="str">'13811255555'); 
insert <span class="kwrd">into TranslationEntity <span class="kwrd">values(1,<span class="str">'CHS',<span class="str">'工商银行'); 
insert <span class="kwrd">into TranslationEntity <span class="kwrd">values(2,<span class="str">'CHT',<span class="str">'工商銀行'); 
insert <span class="kwrd">into TranslationEntity <span class="kwrd">values(3,<span class="str">'ENG',<span class="str">'ICBC'); 
insert <span class="kwrd">into TranslationEntity <span class="kwrd">values(4,<span class="str">'中国北京'); 
insert <span class="kwrd">into TranslationEntity <span class="kwrd">values(5,<span class="str">'中國北京'); 
insert <span class="kwrd">into TranslationEntity <span class="kwrd">values(6,Beijing'); 
                        (编辑:莱芜站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |