当前位置:Gxlcms > mysql > Oracle基本数据类型存储格式浅析(一)字符类型

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

时间:2021-07-01 10:21:17 帮助过:30人阅读

主要说明字符类型的存储式。主要包括char、varchar2和long等几种类型。 1 实验(数字,英文字母) 1.1 建表 SQL create table test_char(char_col char(10), varchar_col varchar2(10), long_col long) tablespace assm; Table created SQL insert into test

主要说明字符类型的存储格式。主要包括char、varchar2和long等几种类型。

1 实验(数字,英文字母)

1.1 建表

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

Table created

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

1 row inserted

SQL> commit;

Commit complete

SQL> select a.*,

2 rowid,

3 dbms_rowid.rowid_object(rowid) obj#,

4 dbms_rowid.rowid_relative_fno(rowid) file#,

5 dbms_rowid.rowid_block_number(rowid) block#,

6 dbms_rowid.rowid_row_number(rowid) row#

7 from test_char a;

CHAR_COL VARCHAR_COL LONG_COL ROWID OBJ# FILE# BLOCK# ROW#

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

abc 123 ,fd AAANCkAAHAAAACYAAA 53412 7 152 0

1.2 dump block

FILE#为7,BLOCK#为152。

SQL> alter system dump datafile 7 block 152;

System altered

SQL> select p.spid

2 from v$session s, v$process p, v$mystat m

3 where s.paddr = p.addr

4 and s.sid = m.sid

5 and rownum = 1;

SPID

-----------

18108

1.3 查看trace文件

根据SPID找到trace文件。

……

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

1.4 结论分析

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

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

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

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

CHR(TO_NUMBER('61','XX'))

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

a

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

ORA-00997: illegal use of LONG datatype

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

2 实验(中文)

2.1 中文

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

NAME VALUE$

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

NLS_CHARACTERSET ZHS16GBK

NLS_NCHAR_CHARACTERSET AL16UTF16

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

1 row inserted

SQL> commit;

Commit complete

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结果,可以清楚的看出,普通英文字符和标点用一个字节表示,而中文字符或中文标点需要两个字节来表示。

2.2 nchar与nvarchar2

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

Table created

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

1 row inserted

SQL> commit;

Commit complete

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

采用nchar,nvarchar2虽然仍然是采用Ascii码存储,但是nchar使用的AL16UTF16字符集,编码长度变为2个字节。这样中文使用两个字节,对于可以用一个字节就表示的英文字符,采用了高位补0的方式凑足2位,这样,对于采用AL16UTF16字符集的nchar类型,无论中文还是英文都用2位字符表示。

转贴:http://www.itpub.net/forum.php?mod=viewthread&tid=308317

人气教程排行