探讨Oracle数据库底层存储---字节序和字符集

存储 存储软件
天主要探讨下Oracle数据库底层存储--字节序和字符集,下面一起来看看吧。

[[276617]]

 概述

今天主要探讨下Oracle数据库底层存储--字节序和字符集,下面一起来看看吧~

1、字节序

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的保存方法如下表所示。

探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集


我们再来看看Little Endian的保存方法。

探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集


根据上面的内容,我们可以知道在Little Endian下,保存整数1920是反向的

以下列出各个服务器平台的ENDIAN格式。

探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集


2、字符集

计算机当初发明时大多用来处理数字,后来慢慢的用来处理文字。问题来了,计算机可不认识全世界这么多文字,甚至连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编码。

探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集


好,下面我们来做一个试验,看看这些字符集里到底保存了什么内容。

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;

探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集



探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集


在上面我们新建一张表,表有两个字段,COL1的字段类型为VARCHAR2使用的是数据库字符集(ZHS16GBK),COL2的字段类型为NVARCHAR2使用国家字符集(AL16UTF16)。往两个字段插入了同样的文本内容'DBSEEKER+广东省广州市'。

接下来,我们DUMP了字段保存的十六进制内容,观察到字段COL1的长度为21个字节,而字段COL2的长度为30字节,为什么同样的文本内容保存在VARCHAR2和NVARCHAR2里面,底层的存储内容完全不同呢?

原因就在于COL1和COL2使用了不同的字符集,不同字符集对应相同文字编码定义也是不一样的。

COL1使用GBK编码,各个字节对应的字符。

探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集


COL2使用UTF16编码,各个字节对应的字符。

探讨Oracle数据库底层存储---字节序和字符集探讨Oracle数据库底层存储---字节序和字符集


通过上面观察,我们可以知道GBK编码是变长的,英文字母用1个字节保存,汉字用2个字节来保存。而UTF16则都是用2个字节来保存。Oracle数据文件里保存的文本字段内容就是各种编码表相对应的字符编码。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2010-04-21 09:49:10

Oracle数据库字符

2010-04-13 12:23:34

Oracle数据库

2010-04-13 13:24:04

Oracle数据库

2010-04-23 10:18:42

Oracle数据库字符

2010-05-10 11:50:33

Oracle数据库字符

2009-11-20 17:06:49

Oracle数据库字符

2011-04-11 11:05:12

Oracle字符集

2010-04-27 13:21:58

Oracle数据字符集

2011-08-15 21:17:38

Oracle数据库字符集

2010-04-30 10:16:22

Oracle字符集

2011-04-11 10:59:33

Oracle字符集

2009-11-20 16:52:35

Oracle字符集

2011-05-20 13:24:39

oracle字符集

2010-01-27 09:55:06

Linux网络字节序主机字节序

2011-05-18 10:36:21

数据库数据导入

2010-05-06 18:01:07

Oracle Expr

2010-04-28 17:29:07

Oracle字符集

2019-09-10 07:58:01

字符集MySQL数据库

2010-02-23 13:48:59

CentOS Data

2011-05-16 13:15:55

MySQL存储字符集
点赞
收藏

51CTO技术栈公众号