分享
 
 
 

Oracle基本数据类型存储格式浅析(一)-字符类型

王朝oracle·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

前一阵看完文档,对Oracle的基本数据类型的存储格式有了一些了解,最近有做了一些测试进行了验证。

打算整理总结一下,这一篇主要说明字符类型的存储格式。主要包括char、varchar2和long等几种类型。

SQL> create table test_char (char_col char(10), varchar_col varchar2(10), long_col long);

表已创建。

SQL> insert into test_char values ('abc', '123', ',fd');

已创建 1 行。

SQL> commit;

提交完成。

SQL> select rowid from test_char;

ROWID

------------------

AAAB3LAAFAAAAAgAAA

根据rowid的定义规则,第7~9位是表示的是数据文件,F表示5,而10~15位表示的是在这个数据文件中的第几个BLOCK,g表示32。(rowid编码相当于64进制。用A~Z a~z 0~9 + /共64个字符表示。A表示0,B表示1,……,a表示26,……,0表示52,……,+表示62,/表示63。)

我们根据计算的结果去dump这个block。

SQL> ALTER SYSTEM DUMP DATAFILE 5 BLOCK 32;

系统已更改。

打开产生的trace文件:

data_block_dump,data header at 0x3421064

===============

tsiz: 0x1f98

hsiz: 0x14

pbl: 0x03421064

bdba: 0x01400020

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f82

avsp=0x1f6e

tosp=0x1f6e

0xe:pti[0] nrow=1 offs=0

0x12:pri[0] offs=0x1f82

block_row_dump:

tab 0, row 0, @0x1f82

tl: 22 fb: --H-FL-- lb: 0x1 cc: 3

col 0: [10] 61 62 63 20 20 20 20 20 20 20

col 1: [ 3] 31 32 33

col 2: [ 3] 2c 66 64

end_of_block_dump

End dump data blocks tsn: 5 file#: 5 minblk 32 maxblk 32

观察dump出来的结果,可以发现以下几点:

1.对于每个字段,除了保存字段的值以外,还会保存当前字段中数据的长度。而且,oracle显然没有把字段的长度定义或类型定义保存在block中,这些信息保存在oracle的数据字典里面。

2. 根据dump的结果,可以清楚的看到,字符类型在数据库中是以ascii格式存储的。

SQL> select chr(to_number('61', 'xx')) from dual;

CH

--

a

3.char类型为定长格式,存储的时候会在字符串后面填补空格,而varchar2和long类型都是变长的。

SQL> SELECT DUMP(CHAR_COL, 16) D_CHAR FROM TEST_CHAR;

D_CHAR

-------------------------------------------------------------

Typ=96 Len=10: 61,62,63,20,20,20,20,20,20,20

SQL> SELECT DUMP(VARCHAR_COL, 16) D_VARCHAR2 FROM TEST_CHAR;

D_VARCHAR2

-------------------------------------------------------------

Typ=1 Len=3: 31,32,33

SQL> SELECT DUMP(LONG_COL, 16) D_VARCHAR2 FROM TEST_CHAR;

SELECT DUMP(LONG_COL, 16) D_VARCHAR2 FROM TEST_CHAR

*

ERROR 位于第 1 行:

ORA-00997: 非法使用 LONG 数据类型

由于DUMP不支持LONG类型,因此我们使用了alter system dump block的方式,通过比较两种方式得到的结果,发现DUMP()函数不但方便,结果清楚,而且指出了进行DUMP的数据类型,在以后的例子中,除非必要的情况,否则都会采用DUMP()函数的方式进行说明。

下面看一下插入中文的情况,首先看一下数据库的字符集

SQL> select name, value$ from sys.props$ where name like '%CHARACTERSET%';

NAME VALUE$

------------------------------ ------------------------------

NLS_CHARACTERSET ZHS16GBK

NLS_NCHAR_CHARACTERSET AL16UTF16

SQL> insert into test_char values ('定长', '变长', null);

已创建 1 行。

SQL> SELECT DUMP(CHAR_COL, 16) D_CHAR FROM TEST_CHAR;

D_CHAR

----------------------------------------------------------------

Typ=96 Len=10: 61,62,63,20,20,20,20,20,20,20

Typ=96 Len=10: b6,a8,b3,a4,20,20,20,20,20,20

SQL> SELECT DUMP(VARCHAR_COL, 16) D_VARCHAR2 FROM TEST_CHAR;

D_VARCHAR2

----------------------------------------------------------------

Typ=1 Len=3: 31,32,33

Typ=1 Len=4: b1,e4,b3,a4

根据dump结果,可以清楚的看出,普通英文字符和标点用一个字节表示,而中文字符或中文标点需要两个字节来表示。

下面,对比一下nchar和nvarchar2与char、varchar2类型有什么不同。

SQL> create table test_nchar (nchar_col nchar(10), nvarchar_col nvarchar2(10));

表已创建。

SQL> insert into test_nchar values ('nchar定长', 'nvarchar变长');

已创建 1 行。

从这里已经可以看出一些不同了,假如按照刚才中文的计算方法,'nvarchar变长'的长度是8+2*2=12已经超过了数据类型定义的大小,可是为什么插入成功了?

还是dump一下看看结果吧。

SQL> select dump(nchar_col, 16) from test_nchar;

DUMP(NCHAR_COL,16)

--------------------------------------------------------------

Typ=96 Len=20: 0,6e,0,63,0,68,0,61,0,72,5b,9a,95,7f,0,20,0,20,0,20

SQL> select dump(nvarchar_col, 16) from test_nchar;

DUMP(NVARCHAR_COL,16)

--------------------------------------------------------------

Typ=1 Len=20: 0,6e,0,76,0,61,0,72,0,63,0,68,0,61,0,72,53,d8,95,7f

这下就明白了,虽然仍然是采用ascii码存储,但是nchar使用的AL16UTF16字符集,编码长度变为2个字节。这样中文使用两个字节,对于可以用一个字节就表示的英文字符,采用了高位补0的方式凑足2位,这样,对于采用AL16UTF16字符集的nchar类型,无论中文还是英文都用2位字符表示。因此'nvarchar变长'的长度是10,并没有超过数据类型的限制。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有