之前做的项目涉及到中国大陆和纽伦新港的用户使用,也就需要做成一个多语言的系统,现在总结下其中一些经验和思考。

首先我们需要确认我们要做的系统,多语言到底是要做多少种语言,以后会不会要求增加更多的语言。比如我们做一个给中国大陆和纽伦新港使用的系统,可以确定的语言就是简体中文、繁体中文和英语,而且可以确定以后也不会增加语言。确定以后是否需要增加语言这一点很重要,决定了我们在数据库设计时,是否需要考虑多语上的扩展性。

先说下在数据库设计时,可以有以下方案实现多语:

一、为每个多语字段建立对应语言的字段列。

比如我们有一个客户表,记录了客户Id、客户名称、客户地址、客户电话等,其中客户名称和客户地址是多语的,而且需要支持简体中文、繁体中文和英语,于是我们可以将客户表设计如下:

create table Client

(

ClientId int primary key,

NameChs nvarchar(50),

NameCht nvarchar(50),

NameEng varchar(200),

AddressChs nvarchar(50),

AddressCht nvarchar(50),

AddressEng varchar(200),

TelephoneNumber varchar(50)

)

这样做的优点是容易理解,容易查询,一个客户实例对应的就是数据库中的一条数据,与普通的非多语数据库无异,而且由于没有形成新的表,所以也不需要额外的Join,所以查询效率很高:

insert into Client values(1,'工商银行','工商銀行','ICBC','中国北京','中國北京','China,Beijing','13811255555');

select *

from Client c

where c.ClientId=1

二、建立统一的翻译表,在翻译表中使用多列存储多语言,然后在实体表中外键引用翻译表。

create table Translation

(

TranslationId int primary key,

TextChs nvarchar(200),

TextCht nvarchar(200),

TextEng varchar(200),

)

create table Client

(

ClientId int primary key,

NameTranId int references Translation(TranslationId),

AddressTranId int references Translation(TranslationId),

TelephoneNumber varchar(200)

)

这样要查询数据时,需要将Translation表JOIN2次,获得对应的Name和Address的多语。

insert into Translation values(10,'工商银行','工商銀行','ICBC');

insert into Translation values(20,'中国北京','中國北京','China,Beijing');

insert into Client values(1,10,20,'13811255555');

select c.ClientId,c.TelephoneNumber,

tn.TextChs as NameChs,tn.TextCht as NameCht,tn.TextEng as NameEng,

ta.TextChs as AddressChs,ta.TextCht as AddressCht,ta.TextEng as AddressEng

from Client c

inner join Translation tn

on c.NameTranId=tn.TranslationId

inner join Translation ta

on c.AddressTranId=ta.TranslationIdwhere

where c.ClientId=1

以上介绍的方法都是将多语作为列输出,也就是说有多少种语言就会有多少对于的列,不利于语言的增加下面再介绍将语言以数据行的形式保存的设计方法,这种方法可以在后期任意增加语言而不改动数据库Schema.

三、将每个表中需要多语的字段独立出来,形成一个对应的多语表。

多语表外键关联原表,每个需要多语的字段在多语表中对应一列,多语表中增加“语言”字段。同样以Client表为例,那么对应的表结构是:

create table Client

(

ClientId int primary key,

TelephoneNumber varchar(200)

)

create table Client_MultiLanguages

(

CLId int primary key,

ClientId int references Client(ClientId),

Name nvarchar(200),

Address nvarchar(200),

Language char(3)

)

这样的优点是便于扩展,在Schema中并没有定义具体的语言,所以如果要增加语言的话,只需要在多语表中增加一行对应的数据即可。查询也相对比较简单,执行要将原表与对应的多语表JOIN,然后跟上具体的语言作为WHERE条件,即可完成对数据的查询,比如要查询Id为1的Client对象的英语实例:

insert into Client values(1,'13811255555');

insert into Client_MultiLanguages values(1,1,'工商银行','中国北京','CHS');

insert into Client_MultiLanguages values(2,1,'工商銀行','中國北京','CHT');

insert into Client_MultiLanguages values(3,1,'ICBC','China,Beijing','ENG');

select c.*,cm.Name,cm.Address

from Client c inner join Client_MultiLanguages cm

on c.ClientId=cm.ClientId

where c.ClientId=1 and cm.Language='ENG'

四、建立统一翻译表和对应的多语表,在每个多语列指向翻译表。

create table Translation

(

TranslationId int primary key

)

create table Client

(

ClientId int primary key,

NameTranId int references Translation(TranslationId),

AddressTranId int references Translation(TranslationId),

TelephoneNumber varchar(200)

)

create table TranslationEntity

(

TranslationEntityId int primary key,

TranslationId int references Translation(TranslationId),

Language char(3),

TranslatedText nvarchar(200)

)

如果要查询Id为1的Client对应的英语实例,那么脚本为:

insert into Translation values(10);

insert into Translation values(20);

insert into Client values(1,10,20,'13811255555');

insert into TranslationEntity values(1,10,'CHS','工商银行');

insert into TranslationEntity values(2,10,'CHT','工商銀行');

insert into TranslationEntity values(3,10,'ENG','ICBC');

insert into TranslationEntity values(4,20,'CHS','中国北京');

insert into TranslationEntity values(5,20,'CHT','中國北京');

insert into TranslationEntity values(6,20,'ENG','China,Beijing');

select c.ClientId,tne.TranslatedText as Name,tae.TranslatedText as Address,c.TelephoneNumber

from Client c

inner join TranslationEntity tne

on c.NameTranId=tne.TranslationId

inner join TranslationEntity tae

on c.AddressTranId=tae.TranslationId

where c.ClientId=1 and tne.Language='ENG' and tae.Language='ENG'

这个数据的插入和查询也太复杂了。同时也可以注意到在查询时根本没有用到Translation表,其实这个表只是标识每个数据实例中的多语字段,可以直接使用数据库的Sequence生成或者使用GUID,只要保证全局唯一即可。另外也可以注意到在查询时JOIN了2次TranslationEntity 表,如果一个表的多语字段比较多,比如有10个字段有多语,那么查询是就需要JOIN10次,这个效率会很低。另外还可以注意到,在WHERE条件中写了2次Language='ENG',如果多个多语字段,那么就要写多次。刚才这个查询写的不够严谨,因为不能保证Name字段和Address字段必然就有英文值,如果没有英文值会导致查询结果为空,所以正确的写法应该是:

select c.ClientId,tne.TranslatedText as Name,tae.TranslatedText as Address,c.TelephoneNumber

from Client c

left join TranslationEntity tne

on c.NameTranId=tne.TranslationId and tne.Language='ENG'

left join TranslationEntity tae

on c.AddressTranId=tae.TranslationId and tae.Language='ENG'

where c.ClientId=1

实际项目中,如果我们使用了NHibernate等ORMapping工具,那么多语字段就会映射成一个集合,所以对于某种语言的实例,那么需要执行N+1次SQL查询,而不是JOIN查询,N是该对象中多语的属性个数.

mysql多语言运营设计_多语言系统的数据库设计相关推荐

  1. mysql逻辑设计_一文看懂数据库设计之逻辑设计,值得收藏

    概述 数据库逻辑设计是从事数据库应用设计.开发.运行维护等各方面工作的一个重要的基础性工作.根据不同业务和应用需求,确定并遵循数据库逻辑设计原则,例如按照第三范式开展逻辑设计,不仅能满足减少数据冗余. ...

  2. java校院导游程序课程设计_校园导游系统 数据结构课程设计(有源程序)

    内容介绍 原文档由会员 莎士比亚 发布 论文标准WORD格式排版 附源程序 海南大学校园导游系统 一. 意义 此程序可以作为庞大的旅游信息查询系统的一个子程序. 二. 程序设计思想 1. 从海南大学的 ...

  3. mysql数据库需求分析工具_一份全面的“数据库设计需求分析”是怎样的?

    原标题:一份全面的"数据库设计需求分析"是怎样的? 本文笔者将与大家分析数据库外部设计需求.结构设计需求.运用设计需求以及安全保密设计需求. 数据库设计需求 1. 需求概述 建立完 ...

  4. mysql的表面sno大全_学生表学号sno数据库

    Microsoft SQL Server 2005习题汇总小结 先建student ,course,sc表: CREATE TABLE Student ( Sno     char(7)   PRIM ...

  5. figma设计_如何在Figma中构建设计入门套件(第1部分)

    figma设计 Figma教程 (Figma Tutorial) Do you like staring at a blank canvas every time you start a new pr ...

  6. ## 大一java课程设计_航班查询系统(我是小白)

    大一java课程设计_航班查询系统(我是小白) 备注:第一个java程序有借鉴别人的成分,因为忘了在哪个大佬上面借鉴的,所以在此备注,如有侵权,请联系删除,(仅用于学习使用,并未想盈利) 框体介绍 一 ...

  7. MySQL数据库设计作业 ——《网上书店系统》数据库设计实验报告

    数据库设计作业--<网上书店系统>数据库设计 一.功能需求 普通用户:可以进行最基础的登陆操作,可浏览图书.按类别查询图书.查看 图书的详细信息,还可以注册成为会员. 会员:需要填写详细信 ...

  8. 1、微信点餐系统之数据库设计

    1.微信点餐系统之数据库设计 ---- ----商品表格 ---- CREATE TABLE `product_info` (`product_id` VARCHAR(32) NOT NULL COM ...

  9. 关于电子支付系统的数据库设计

    现在,大到银行等金额机构,小到城市一卡通,直到餐馆等路边小店的会员系统都在使用电子支付进行结算. 根据系统应用的用户规模和交易量,系统的数据库设计也是不同的. 那种账户一年才几个,交易量不到一万笔,交 ...

  10. 饮料自动售货机5角的c语言,自动售货机图形拟系统需求分析与设计报告完成稿.doc...

    自动售货机图形拟系统需求分析与设计报告完成稿 C语言课程设计 需求分析与系统设计报告 目 录 1 引言2 1.1背景2 1.2定义2 1.3参考资料2 2 需求分析3 2.1需求分析3 2.2运行环境 ...

最新文章

  1. 北京大学现代农业研究院张华伟实验室招聘启示
  2. 看看那些不讲码德的坏习惯
  3. 求幂,我居然又没做出来
  4. macappstore登不上去_Mac 链接不上AppStore的解决方法
  5. 4.24企业数据库应用实践技术沙龙
  6. [转]C#网络编程(同步传输字符串) - Part.2
  7. python配置文件密码管理_用户配置文件和密码配置文件,用户组管理和用户管理...
  8. 【协作通信】基于matlab协作通信仿真【含Matlab源码 1006期】
  9. ModuleNotFoundError: No module named 'pytz'
  10. 机器人动力学建模之理解惯性张量
  11. 怎样才能安全使用计算机和手机,手机如何与电脑共享文件
  12. linux脚本设置字体颜色,xshell设置字体及背景颜色方法详细教程
  13. 【Python】多进程 AttributeError: Can‘t pickle local object
  14. 一个等号(=)和三个等号和两个等号的区别(“===”和“==”)
  15. 无法打开此计算机的组策略,无法运行gpedit.msc(组策略)的解决
  16. Java的发展历史以及当前Java的发展现状
  17. w讠ndows Boot Manager,求大神解答:急急电脑开机出现windows boot manager无法开机怎么办,...
  18. 云南计算机一级b成绩查询入口,云南计算机一级考试成绩查询入口
  19. Deepin安装Wireshark
  20. Jmeter常用操作——配置多用户并发

热门文章

  1. fs和php的区别,优缺点评测飞科fs318和fs360有啥区别?哪个好?真实评测体验曝光...
  2. mysql 时间类型转化_Mysql 字段类型转化 和 时间类型相关处理
  3. Facebook如何“养号”干货分享
  4. Facebook广告兴趣定位终极指南经验分享
  5. java spring多数据源配置文件_深入理解spring多数据源配置
  6. 吴恩达|机器学习作业7.0.k-means聚类
  7. Redis基础(三)——数据类型
  8. (筆記) 如何避免iTunes自動備份? (iPhone) (iPad) (iOS) (iTunes)
  9. “精钢云”落地:鞍钢携手金山云推动中国制造
  10. c++ 输出二进制_Q音直播编译优化与二进制集成方案