oracle-字符集问题

什么是oracle字符集

     字符集有很多种,最初的字符集是ASCII 由于ASCII支持的字符很有限,因此随后又出现了很多的编码方案。这些编码方案大部分都是包含了ASCII的。大部分的系统都是基于ASCII编码的。
    由于亚洲国家的字符集相对复杂一些,因此一般都使用了两个及以上的字节进行编码的方案。对于简体中文,GB2312码是国家1981年实施的编码标准。通行于大陆。目前最新的汉字字符集是2000年的GB18030,它是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文,蒙文,维吾尔文等主要的少数民族文字。目前简体windows的缺省内码还是GBK。
    由于编码方案太多而且彼此之间不兼容,存在相互之间存在冲突的情况。为此国际标准化组织(ISO)制定了ISO10646码表,而Unicode协会制定了Unicode规范。 从Unicode2.0开始,Unicode项目采用了与ISO10646-1相同的字库和字码。但目前两个项目仍都存在。并独立的公布各自的标准。

    Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。

    Oracle的字符集名字一般由以下部分组成;语言或区域、表示一个字符的比特位数、标准字符集名称。oracle字符集UTU8和UTFE不符合此规定,其它基本都是这种格式。
如:
 中文字符集ZHS16GBK 表示简体中文(ZHT为繁体中文),一个字符需要16位比特,标准的字符集名称为GBK, GBK编码标准是 GB2312编码标准的扩展。
 US7ASCII  表示区域是US,用7个比特位表示一个字符,标准的字符集名称为ASCII。


字符集的处理 

通常在我们的现实环境中,存在3个字符集设置。

   第一: 客户端应用字符集(Client Application Character Set)

   第二: 客户端NLS_LANG参数设置

   第三: 服务器端,数据库字符集(Character Set)设置

  我们说,一个字符在客户端应用(比如SQLPLUS,CMD,NOTEPAD等)中以怎样的字符显示取决于客户端操作系统,客户端能够显示怎样的字符,
我们就可以在应用中录入这些字符,至于这些字符能否在数据库中正常存储,就和另外的两个字符集设置紧密相关了。

在传输过程中,客户端NLS_LANG主要用于进行转换判断

如果NLS_LANG等于数据库字符集,则不进行任何转换直接把字符插入数据库

如果不同则进行转换,转换主要有两个任务

       •如果存在对应关系,则把相应二进制编码经过映射后(这一步映射以后,所代表的字符可能发生转换)传递给数据库。
       •如果不存在对应关系,则传递一个替换字符。

数据库字符集,在和客户端NLS_LANG不同时,会把经过NLS_LANG转换的字符进行进一步处理。

例如:

测试环境:

客户端应用为中文18030字符集

NLS_LANG设置为US7ASCII字符集

数据库CHARACTER SET为ZHS16GBK

结果出现乱码,这个测试说明在US7ASCII转换中文的时候除去了首位的 1,这样就丢失了元数据,导致乱码出现,NLS_LANG的转换作用由此可加一斑!

例如:

客户端字符集应用为中文GB18030

客户端NLS_LANG为US7ASCII

数据库字符集为US7ASCII

我们知道这个时候,存入的数据,数据库不进行任何转换,在测试中,我们看到中文在US7ASCII字符集下得以正确显示。

以上来自

http://www.eygle.com/special/NLS_CHARACTER_SET_06.htm

http://wenku.baidu.com/view/47fdab8984868762caaed583.html


查询oracle server端的字符集

     有很多种方法可以查出oracle server端的字符集,比较直观的查询方法有:

    select * from v$nls_parameters where parameter='NLS_CHARACTERSET';

         或者
    select userenv('language') from dual; 


字符集对字符存储的影响

 针对于oracle

1, 数据库字符集为ZHS16BGK,汉字在数据库存放的时候占用两个字节;
2, 数据库字符集为UTF8,汉字在数据库里存放的时候占用三个字节;

   由于字符集不同,导致现在数据库IMP的时候有些表的字段长度不够,出现ORA-12899: value too large for column的错误。
  通过修改字符集可以解决这种问题。


修改oracle的字符集 

     oracle的字符集有互相的包容关系。如us7ascii就是 zhs16gbk的子集,从us7ascii到zhs16gbk不会有数据解释上的问题,不会有数据丢失。

     在所有的字符集中utf8应该是最大,因为它基于unicode,双字节保存字符(也因此在存储空间上占用更多)。
    一旦数据库创建后,数据库的字符集理论上讲是不能改变的。因此,在设计和安装之初考虑使用哪一种字符集十分重要。根据Oracle的官方说明,字符集的转换是从子集到超集受支持,反之不行。如果两种字符集之间根本没有子集和超集的关系,那么字符集的转换是不受oracle支持的。对数据库server而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改oracle数据库 server端的字符集。特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。

以上来自

    http://www.blogjava.net/chenying19890808/

如何选择合适的数据库字符集

     对于只存储英文信息的数据库来说,一般采用US7ASCII等一些单字节的字符集就比较合适,在性能和空间上也是最优。
     对于主要存储中文信息的数据库来说,一般采用ZHS16GBK的编码格式。

     对于国际化的考虑,一般采用采用AL32UTF8或UTF8编码格式。

     目前出于国际化的需要,软件需要可以对不同的语言文字进行处理,尤其一个系统中需要容纳多种语言文字的时候,一般都会采用unicode这样的通用解决方案。即使会有一些空间和运行效率的损失也是值得的。此时数据库字符集建议采用AL32UTF8或UTF8编码,一种比较理想的模式就是由程序负责编码格式的转换,而数据库只提供一个透明的数据存储。
    如客户在简体中文XP的环境下,输入的中文编码属于GBK编码。在客户输入结束后,程序首先判断客户的本地环境,并把编码转换成Unicode,并通过net网络传送到服务器端。由于数据库的字符集为UTF8,直接放到数据库中,不用字符转换。如果程序不支持转换,在客户输入结束后,程序直接把数据通过Net网络传送到服务器端。由oracle本身把客户端的编码转换成UTF8格式,再把数据按UTF8格式存储到数据库中。由oracle数据库来自动进行转换。
由于UTF8是其他字符集的超集,因此在转换过程中不会发生数据丢失的情况。对于英文字符,在utf8中使用单字节存储,转换的工作量很小,可以忽略,而对于一些亚洲字符集,在UTF8中一般需要两到三个字节存储,需要的数据库空间增加,而且转换的工作量也相对大一些,性能也会有一些损失。

 以上来自

 http://wenku.baidu.com/view/47fdab8984868762caaed583.html


 













 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值