关于管理系统型项目的国际化/多语言思考

数据表设计-字符集考虑

数据表设计中提到的多语言/国际化。其实也就是字符集的考虑,为什么这么说呢?

首先在计算机中,所有的数据在存储和运算时,都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0)。

然后我们要考虑字符编码问题。

ASCII码
ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。 
0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。32~126(共95个)是字符(32是空格),其中48~57为0到9十个阿拉伯数字。 
65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。

Unicode
UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。

UTF-8
是以字节为单位对Unicode进行编码。 

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。 
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

UTF-16
UTF-16编码是以16位无符号整型数据为单位的。能够对Unicode的所有1,112,064个有效代码点进行编码。编码是可变长度的,因为编码点是用一个或两个16位代码单元编码的。 
Unicode编码0x10000-0x10FFFF的UTF-16编码有两个WORD(一个8位叫做字节,一个16位称为一个字,或者双字节),第一个WORD的高6位是110110,第二个WORD的高6位是110111。可见,第一个WORD的取值范围(二进制)是11011000 00000000到11011011 11111111,即0xD800-0xDBFF。第二个WORD的取值范围(二进制)是11011100 00000000到11011111 11111111,即0xDC00-0xDFFF。

1.首先按现在17个平面的限制,辅助平面的码位是U+10000到U+10FFFF,我们得到了一个辅助平面的Unicode码时,先减去BMP的码数0x10000,得到的数介于0到0xFFFFF之间,最多用20bit表示 
2.然后我们把20bit从中间隔开,分为高位的10bit和低位的10bit 
3.我们知道10bit的取值范围是0到0x3FF,高位的10bit加上固定值0xD800,得到的值叫做前导代理(lead surrogate),范围是0xD800到0xDBFF 
4.低位的10bit加上固定值0xDC00,得到的值叫做后尾代理(tail surrogate),范围是0xDC00到0xDFFF。这样一来,不仅高位和低位都落在了保留区块内,而且彼此还做了区分。

如果你没有耐心看完上面关于字符的介绍;那你就记住;不能的文字所用的字符集不一样;需要的字节单位长度不一样,就好比英文只有26个字母;所以我就定义了一个26位长度数组;当我输入26下标时;就会产生数组越界异常。所以在一开始如果的你的程序需要支持中文的;请使用UTF-8,如果你需要存储像越南文之类的;你可能还需要考虑到使用UTF-16的字符。

编码更多的考虑你可以参考 https://www.ibm.com/support/knowledgecenter/zh/SSSA5P_12.7.0/ilog.odms.cplex.help/CPLEX/UsrMan/topics/progr_consid/input_output/manageIO_encodings.html

数据表设计-常量设计

一般来说一个业务系统将会涉及到很多的业务常量,如性别:男/女,爱好:计算机/篮球/足球...

在不考虑多语言版本的时候我们数据结构通常是这样的

id constant_code constant_code constant_value
1 gender male
2 gender female
... ... ... ...

这是我们可以通过select * from constants where constant_code = 'gender' 拿到所有的关于性别的code和value。

而当你需要考虑到多语言版本的时候;你需要考虑到把i18n加入,也就说此时的contant_value列不再存储一个具体语言版本的值,而是一个能映射到你国际化(i18n)的key。

id constant_code constant_code constant_value
1 gender male i18n_male_key
2 gender female i18n_female_key
... ... ... ...

 

id locale i18n_code i18n_value
1 zh_CN i18n_male_key
2 en_US i18n_male_key male
... ... ... ...

这是我们可以通过select * from constants left join i18n on i18n_code = constant_value   where constant_code = 'gender' and locale = '{locale}' 拿到所有的关于性别的code和value。

posted @ 2018-12-26 13:50  dev-lluo  阅读(792)  评论(0编辑  收藏  举报
个人博客:来点啤酒