今天主要探讨下Oracle数据库底层存储--字节序和字符集,下面一起来看看吧~
Oracle安装在不同的服务器架构平台,数据文件所采用的字节序也不相同。字节序有两种,Big Endian和Little Endian。比如一般我们windows或者linux服务器用的CPU是Intel/AMD架构,那么数据文件保存格式为Little Endian,如果用的是IBM的Power PC,那么数据文件保存格式为Big Endian。
Big Endian和Little Endian具体在保存数据时有什么区别呢?我们举例说明。
整数1920如果用4个字节(十六进制0X00000780)保存,那么在Big Endian的保存方法如下表所示。
我们再来看看Little Endian的保存方法。
根据上面的内容,我们可以知道在Little Endian下,保存整数1920是反向的
以下列出各个服务器平台的ENDIAN格式。
计算机当初发明时大多用来处理数字,后来慢慢的用来处理文字。问题来了,计算机可不认识全世界这么多文字,甚至连26个英文字母也不认识。于是美国国家标准协会ANSI开始制作标准,比如用65表示字母A,用66来表示字母B,包括26个大小写字母,数字和一些符号(100多个),这就是最初的ASCII码。当初ASCII码没有超过128个,只用了7位来表示,最高位留给用作奇偶校验。后来又被欧洲扩展到了8位,可以用来表示256个字符。
ASCII码并没有包括中文,要让计算机认识中文,中国的标准化机构也开始制作了一些标准(GBK)。中国的汉字太多了,用一个字节可装不下这么多(8个二进制位最多表示256个字符),于是采用了2个字节(理论上可以表示65536个字符),其他国家和地区也没有闲着,比如日本的Shift_JIS编码,香港台湾的BIG5编码,于是全世界产生了各种各种的字符编码。
这样问题又来了,而且是大问题。大家都各搞各的,这么多编码,自己本地传输信息当然没有问题。但是当一个中国人发GBK编码的中文邮件给日本人,日本人的电脑如果只认识Shift_JIS编码,那么计算机将会把所有GBK编码按照Shift_JIS编码来解释,于是日本人看到的是所谓的“乱码”。之所以叫所谓,因为计算机自认为它并没有做错,那些“乱码”也是对应的字符,只是不常用,日本人看不懂而已,计算机懂的。
于是地球上的标准化组织领导们又开会讨论了,还提出了一个伟大的想法,这就是UNICODE字符集。这种字符集的想法是用一套字符集把地球上所有的文字都包括进来。当然2个字节可装不下全世界的所有字符,采用了4个字节(理论上可以表示4294967296个字符)。用UNICODE字符集实现的编码有UTF32/UTF16/UTF8。
上面扯了这么多,那么我们在新建数据库的时候,需要选择数据库的数据库字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。比如我们选择数据库字符集为 ZHS16GBK,国家字符集为AL16UTF16。它表示这个数据库里Char,Varchar2采用的是GBK的编码,而Nchar,Nvarchar2,Nclob采用UTF16编码。
好,下面我们来做一个试验,看看这些字符集里到底保存了什么内容。
SQL> SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER LIKE '%CHARACTERSET%'; SQL> CREATE TABLE TESTCHAR (COL1 VARCHAR2(100),COL2 NVARCHAR2(100)); SQL> INSERT INTO TESTCHAR VALUES('DBSEEKER+广东省广州市','DBSEEKER+广东省广州市'); SQL> SELECT DUMP(COL1,16),DUMP(COL2,16) FROM TESTCHAR;
在上面我们新建一张表,表有两个字段,COL1的字段类型为VARCHAR2使用的是数据库字符集(ZHS16GBK),COL2的字段类型为NVARCHAR2使用国家字符集(AL16UTF16)。往两个字段插入了同样的文本内容'DBSEEKER+广东省广州市'。
接下来,我们DUMP了字段保存的十六进制内容,观察到字段COL1的长度为21个字节,而字段COL2的长度为30字节,为什么同样的文本内容保存在VARCHAR2和NVARCHAR2里面,底层的存储内容完全不同呢?
原因就在于COL1和COL2使用了不同的字符集,不同字符集对应相同文字编码定义也是不一样的。
COL1使用GBK编码,各个字节对应的字符。
COL2使用UTF16编码,各个字节对应的字符。
通过上面观察,我们可以知道GBK编码是变长的,英文字母用1个字节保存,汉字用2个字节来保存。而UTF16则都是用2个字节来保存。Oracle数据文件里保存的文本字段内容就是各种编码表相对应的字符编码。