概述
今天主要讨论一下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的存储方式如下表所示。
我们来看看Little Endian的保存方式。
根据以上内容我们可以知道,在小端模式下,保存整数1920是取反的
下面列出了每个服务器平台的 ENDIAN 格式。
2.字符集
计算机刚发明时,多用于处理数字,后来才慢慢用于处理文本。 问题来了。 计算机不认识世界上那么多的字符,连26个英文字母也不认识。 于是美国国家标准协会ANSI开始制定标准,比如用65来表示字母A,用66来表示字母B,包括26个大小写字母、数字和一些符号(100多个),这就是原始 ASCII 码。 一开始ASCII码不超过128个,只用7位来表示,最高位留作校验。 后来被欧洲扩展为8位,可以用来表示256个字符。
ASCII码不包含中文。 为了让计算机能听懂中文,中国的标准化组织也开始制定一些标准(GBK)。 中国的汉字太多了,一个字节放不下这么多(8个二进制位最多可以表示256个字符),所以2个字节(理论上可以表示65536个字符),其他国家和地区也没有闲着当时oracle中文占几个字符,比如日本的Shift_JIS编码,港台的BIG5编码,所以世界各地都产生了各种字符编码。
问题又来了,而且是个大问题。 每个人都有自己的方式,那么多代码,当然在本地传递信息是没有问题的。 但是当中国人给日本人发GBK编码的中文邮件时,如果日本人的电脑只看得懂Shift_JIS码,那么电脑会把所有的GBK码都按照Shift_JIS码来解释,所以日本人看到的就是所谓的“乱码”。 ”。之所以这么叫,是因为计算机认为自己没有做错,那些“乱码”也是对应的字符,只是不常用,日本人看不懂,但是计算机理解它们。
于是地球上标准化组织的领导们又开会讨论oracle中文占几个字符,还提出了一个很棒的想法,就是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字段中存储的16进制内容,观察到字段COL1的长度为21字节,而字段COL2的长度为30字节,为什么VARCHAR2和NVARCHAR2中存储了相同的文本内容,底层存储内容是否完全不同?
原因是COL1和COL2使用了不同的字符集,不同的字符集对应不同的字符编码定义。
COL1采用GBK编码,每个字节对应字符。
COL2使用UTF16编码,每个字节对应字符。
通过上面的观察我们可以知道,GBK编码是变长的,英文字母用1个字节存储,汉字用2个字节存储。 UTF16 存储在 2 个字节中。 Oracle数据文件中保存的文本域内容是各种编码表对应的字符编码。
了解这些内容对于分析数据块很有帮助。 更多devops和DBA内容稍后会分享,感兴趣的朋友可以关注~