• Oracle根蒂根基数据规范存储花式浅析(一)——字符规范


       前导发轫:yangtingkun.itpub.net  




     

    前一阵看完文档,对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,并没有跨越数据规范的限制。




    版权声明: 原创作品,容许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。不然将追究法律责任。

  • 相关阅读:
    CentOS7 安装MongoDB 3.0服务
    PXE批量部署linux操作系统
    centos的软件安装方法rpm和yum
    第二章:Posix IPC
    第一章:简介
    Unix网络编程--卷二:进程间通信
    Unix网络编程--卷二:FAQ
    linux下samba环境搭建
    Linux下缓冲区溢出攻击的原理及对策(转载)
    lsof
  • 原文地址:https://www.cnblogs.com/zgqjymx/p/1976097.html
Copyright © 2020-2023  润新知