首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 冲浪宝典 > 网络资源 > Oracle基本数据类型存储格式浅析(一)——字符类型
【标  题】:Oracle基本数据类型存储格式浅析(一)——字符类型
【关键字】:Oracle
【来  源】:http://blog.chinaunix.net/article.php?articleId=27047&blogId=3787

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

前一阵看完文档,对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,并没有超过数据类型的限制。

将Oracle的查询结果输出为文件:【上一篇】
怎么样快速复制表或者是插入数据:【下一篇】
【相关文章】
  • 将Oracle的查询结果输出为文件
  • Oracle导出备份和导入恢复自动产生sql源代码
  • Oracle基本数据类型存储格式浅析(二)——数字类型
  • Oracle 数据库复制常用脚本
  • oracle数据库的启动与关闭
  • ORACLE的环境变量TWO_TASK
  • all installing oracle9i under linux platfrom
  • oracle中pro*c的学习
  • Oracle备份与恢复1
  • Oracle9iR2在ReahatAS3上的升级导致exp不正常的问题
  • 【随机文章】
  • 学习ORCALE的途径
  • SmartCalendar 0.1 beta released!
  • 用Java实现断点续传(HTTP)(2)
  • ASP还是有其局限性
  • C语言密码
  • 將textbox按回車轉為Tab3/17
  • javascript Cookie管理
  • 代码签名和安全邮件的使用
  • TCP/IP各层的安全性和提高各层安全性的方法(二)
  • Java ME应用设计指南之联网重定向
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.