3.11 自定义字符的使用
很多时候,需要存储的字符可能在数据库的字符集中并不存在,这时候我们就可以通过客户端的“TrueType 造字程序”来对空闲代码点进行自定义字符的创建。
在 Windows 上,单击开始→运行→eudcedit,可以启动造字程序,下面我们用造字程序在字符集ChineseGBK下使用代码点AAA1创造一个新字进行测试,如图3-15所示。
图3-15 使用造字程序自造字
造字完成以后,保存该字符,在客户端字符集我们就完成了这个新字符的定义,接下来在菜单栏上单击编辑→输入法链接,将该字符链接到当前输入法中,以便通过输入法输入这个字。
下面我们可以将这个字存入数据库,如图3-16所示。那么接下来的查询这个字可以被正确显示,如图3-17所示。
图3-16 将自造字存入数据库
图3-17 自造字及代码点
我们注意,这个字的编码为170 161,转换为十六进制后正是:AAA1。
也就是说服务器端只管存入了客户端发过去的编码,至于这个编码代表了什么字符数据库服务器并不管,当反向查询时,Oracle 数据库将编码再返回给客户端,客户端依据编码来对应客户端的字符展现,如果客户端存在对应,那么就可以正常显示我们创建的字符,如果不存在,或者客户端定义了不同的编码,那么显示的就将是不同的字符,这和不同字符集的相互转换的原理是相同的,对于本例,我们在另外一个客户端对AAA1定义了不同的字符,则查询的结果如图3-18所示。
图3-18 自造字在不同客户端可能的不同映射
这也就是为什么我们前面说,当进行字符集转换时需要通过csscan进行扫描,其中的一个原因就是因为同一个代码点在不同的字符集下可能代表不同的字符。
总结一下,字符集的实现实际上依赖于数据库端及客户端的字符集文件,只有服务器端字符集文件存在代码点到字符的映射,数据库服务器才知道存储的代码到底代表什么字符;而同样客户端也必须存在相应的代码点到字符的映射关系,这样数据库服务器上的字符传递到客户端之后才能被正确的解码成相应的字符。这就类似调制解调的过程,在传输过程中,自始至终传递的都是字符编码。
只有遵循通用的编码规范,我们的数据才能够通用地被不同的客户端、平台所共享和识别,如果是自定义的字符,那么在不存在定义关系的客户端就无法被识别或者不能被正确识别。