来历:网海拾贝



Oracle基本数据范例存储名堂浅析(一)——字符范例
揭晓人:yangtingkun | 揭晓时分: 2004年十二月09日, 23:47
前一阵看完文档,对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
f搜索引擎优化=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基本数据范例存储名堂浅析(二)——数字范例
揭晓人:yangtingkun | 揭晓时分: 2004年十二月14日, 22:57
这篇文章次要描画NUMBER范例的数据和若何在数据库中存储的。
Oracle的NUMBER范例最多由三个部分构成,这三个部分区分是最高位体现位、数据部分、标记位。此中负数包括标记位,负数不会网罗标记位。别的,数值0比拟特别,它只包括一个数值最高位体现位80,没无数据部分。
负数的最高位体现位年夜于80,负数的最高位体现位小于80。此中一个负数的最高位是个位的话,则最高位体现位为C1,百位、万位依次为C2、C3,百分位、万分为依次为C0、BF。一个负数的最高位为个位的话,最高位体现位为3E,百位、万位依次为3D、3C,百分位、万分位依次为3F、40。
数据部分每一位都体现2位数。这个两位数可以是从0到99,若是是数据本人是负数,则区分用二进制的1到64体现,若是数据本人是负数,则运用二进制65到2体现。
标记位用66体现。
上面的这些是我经由议定DUMP下场总结出来的,关于上面提到的这些关系常数,Oracle之以是如许选择是有事理的,我们后面依据例子也可以推导出来,而且会进一步剖析为什么会采纳这种体式款式体现。这里列出的意思是使年夜家先对NUMBER范例数据有一个或许的熟悉。
上面我们经由议定一个例子过细剖析:
 
SQL> CREATE TABLE TEST_NUMBER (NUMBER_COL NUMBER);
表已创设。
SQL> INSERT INTO TEST_NUMBER VALUES (0);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (1);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (2);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (25);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (123);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (4100);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (132004078);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (2.01);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (0.3);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (0.00000125);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (115.200003);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (-1);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (-5);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (-20032);
已创设 1 行。
SQL> INSERT INTO TEST_NUMBER VALUES (-234.432);
已创设 1 行。
SQL> COMMIT;
提交完成。
SQL> COL D_NUMBER FORMAT A50
SQL> SELECT NUMBER_COL, DUMP(NUMBER_COL, 16) D_NUMBER FROM TEST_NUMBER;
NUMBER_COL D_NUMBER
---------- --------------------------------------------------
         0 Typ=2 Len=1: 80
         1 Typ=2 Len=2: c1,2
         2 Typ=2 Len=2: c1,3
        25 Typ=2 Len=2: c1,1a
       123 Typ=2 Len=3: c2,2,18
      4100 Typ=2 Len=2: c2,2a
 132004078 Typ=2 Len=6: c5,2,21,1,29,4f
      2.01 Typ=2 Len=3: c1,3,2
        .3 Typ=2 Len=2: c0,1f
 .00000125 Typ=2 Len=3: be,2,1a
115.200003 Typ=2 Len=6: c2,2,10,15,1,4
        -1 Typ=2 Len=3: 3e,64,66
        -5 Typ=2 Len=3: 3e,60,66
    -20032 Typ=2 Len=5: 3c,63,65,45,66
  -234.432 Typ=2 Len=6: 3d,63,43,3a,51,66
已选择15行。
 
    上面依据例子掉掉的下场,对每行截至剖析。首先剖析两点基本的。DUMP函数前往的TYPE=2体现DUMP的数据范例是NUMBER,LENGTH=N体现数值在数据库中存储的长度是N。
1.DUMP(0)的下场是0x80,在后面曾经提到,0只要高位体现位,没无数据位。由于0的特别,既不属于负数,也不属于负数,因此运用高位体现位用80体现就充足了,不会和别的数据抵触,Oracle出于浪费空间的思考将后面数据部分省掉了。但是为什么Oracle选择0x80体现0呢?我们晓得负数和负数互为相反数,每个负数都有一个对应的负数。因此若是我们要运用编码体现数值,则暗斧负数和负数的编码应该各占一半,如许才干担保使Oracle体现数据范畴是公道的。而0x80的二进制编码是1000 0000,正好是一个字节编码最年夜值的一半,因此,Oracle选择0x80来体现0,是非常有事理的。
2.DUMP(1)的下场是0xc102,0xc1体现了最高位个位,0x2体现数值是1。首先,Oracle为什么用C1体现个位呢?其实,事理和刚刚的差不多。采纳科学计数法,任何一个实数S都可以描画为A.B×10n,A体现整数部分,B体现小数部分,而N体现10的指数部分。当S年夜于1时,N年夜于便是0,S小于1时,N小于0。也就是说,采纳指数的体式款式体现,N年夜于0和N小于0的情况各占一半旁边时,Oracle所体现的范畴最广。因此,Oracle选择了C1体现个位是最高位的情况。
SQL> SELECT TO_CHAR(ROUND(TO_NUMBER('81', 'XXX') (TO_NUMBER('FF', 'XXX') - TO_NUMBER('81', 'XXX') 1)/2), 'XX') FROM DUAL;
TO_
---
 C1
 
为什么ORACLE运用0x2体现1,而不间接运用0x1体现1呢?Oracle每个字节体现2位数,因此关于这个2位数,出现的可以是0~99共100种可以,成绩出在0这里。Oracle底层是用C言语完成的,我们晓得二进制0在C言语顶用作字符串终结符,Oracle为了防止这个成绩,因此运用了0x1体现0,并依次类推,运用0x64体现99。
3.DUMP(2)的下场是0xc103。
4.DUMP(25)的下场是0xc11a。后面提到,数据部分因此2位为最小单位生活生计的。因此关于25来说,最高位体现位依然是个位,个位上的值是25,依据上面推出的法则,25在存储为0xc11a。
SQL> SELECT TO_CHAR(25 1, 'xx') FROM DUAL;
TO_
---
 1a
 
5.DUMP(123)的下场是0xc20218。由于123最高为是百位,以是最高位体现位为0xc2,百位上是1,用0x02体现,个位上是23,用0x18体现。
6.DUMP(4100)的下场是0xc22a。
注意一点,若是数字最后数位上若是是0,Oracle出于浪费空间的思考不会存储。比方:4100只生活生计百位上的41,12000000只生活生计百位位上的12,512000只生活生计万位上的51和百位上的20。
7.DUMP(132004078)的下场是0xc5022101294f。最高位是亿位,因此用0xC5体现,亿位上是1用0x02体现,百位位上是32用0x21体现,万位上是0用0x01体现,百位上是40用0x29体现,个位上78用0x4F体现。
注意:中心数位上的0不克不及省略。
8.DUMP(2.01)的下场是0xc10302。最高位是个位用0xC1体现,个位上是2用0x03体现,百分位上是1用0x02体现。
注意:个位上面一位是百分位不是非常位。
9.DUMP(0.3)的下场是0xc01f。最高位是百分位,运用0xC0体现,百分位上是30用0x1F体现。
10.DUMP(0.00000125)的下场是0xbe021a。最高位是百万分位,用0xBE体现,最高位上的1用0x02体现,25用0x1a体现。
11.DUMP(115.200003)的下场是0xc20210150104。
12.DUMP(-1)的下场是0x3e6466。最高位个位,用0x3E体现,64体现个位上是1,66是标记位,体现这个数是负数。
负数和负数互为相反数,负数的最高位体现位和它对应的相反数的最高位相加的值是FF。1的最高位体现位是C1,-1的最高位体现位是3E。负数中1用64体现。负数中的数值和它相反数的数据相加是0x66,也就是标记位。负数1用0x02体现,负数1用0x64体现,二者相加是0x66。负数多个一个标识位,用0x66体现。由于负数的体现范畴是0x01到0x64,负数的体现范畴是0x65到0x02。因此,不会在体现数字时出现的0x66体现。
13.DUMP(-5)的下场是0x3e6066。0x3e体现最高位是个位,0x60体现个位上是5,0x66是标记标识位。0x3E加0xC1是0xFF。0x60加0x06的下场是0x66。
14.DUMP(-20032)的下场是0x3c63654566。最高位是万位,负数的万位是0xC3,因此负数的万位是0x3C。万位上是2,负数用0x03体现,负数为0x63,百位上是0,负数用0x01体现,负数运用0x65体现,个位上是32,负数用0x21体现,负数运用0x45体现。0x66是负数体现位。
15.DUMP(-234.432)的下场是0x3d63433a5166。
 
依据Oracle的存储特性,还可以推出Oracle的number范例的取值范畴。
Oracle的concept上是如许描画的:
The following numbers can be stored in a NUMBER column:
Positive numbers in the range 1 x 10-130 to 9.99...9 x 10125 with up to 38 significant digits.
Negative numbers from -1 x 10-130 to 9.99...99 x 10125 with up to 38 significant digits.
Zero.
上面来推导出取值范畴。
来看标记位,0xC1体现个位。
SQL> select to_number('ff', 'xxx') - to_number('c1', 'xxx') from dual;
TO_NUMBER('FF','XXX')-TO_NUMBER('C1','XXX')
-------------------------------------------
                                         62
由于Oracle是两位、两位存储的,因此最高位相等于62×2=124,而且最高位上最年夜值是99,因此负数的最年夜值为9.999……×10125。
SQL> select to_number('c1', 'xxx') - to_number('80', 'xxx') from dual;
TO_NUMBER('C1','XXX')-TO_NUMBER('80','XXX')
-------------------------------------------
                                         65
最高位相等于65×2=130,因此负数的最小值为1×10-130。
负数和负数在各运用了一半的编码,因此具有雷同的极值范畴。
==============================================================
Oracle基本数据范例存储名堂浅析(三)——日期范例(一)
揭晓人:yangtingkun | 揭晓时分: 2004年十二月15日, 14:00
这篇文章描画DATE范例的数据在Oracle中因此何种名堂寄存的。
上面经由议定一个例子截至剖析。
 
SQL> create table test_date (date_col date);
表已创设。
SQL> insert into test_date values (to_date('2000-1-1 0:0:0', 'yyyy-mm-dd hh24:mi:ss'));
已创设 1 行。
SQL> insert into test_date values (to_date('1-1-1 0:0:0', 'yyyy-mm-dd hh24:mi:ss'));
已创设 1 行。
SQL> insert into test_date values (to_date('-1-1-1 0:0:0', 'syyyy-mm-dd hh24:mi:ss'));
已创设 1 行。
SQL> insert into test_date values (to_date('-101-1-1 0:0:0', 'syyyy-mm-dd hh24:mi:ss'));
已创设 1 行。
SQL> insert into test_date values (to_date('-4712-1-1 0:0:0', 'syyyy-mm-dd hh24:mi:ss'));
已创设 1 行。
SQL> insert into test_date values (to_date('9999-12-31 23:59:59', 'syyyy-mm-dd hh24:mi:ss'));
已创设 1 行。
SQL> insert into test_date values (sysdate);
已创设 1 行。
SQL> insert into test_date values (to_date('-4713-1-1 0:0:0', 'syyyy-mm-dd hh24:mi:ss'));
insert into test_date values (to_date('-4713-1-1 0:0:0', 'syyyy-mm-dd hh24:mi:ss'))
                                      *
ERROR 位于第 1 行:
ORA-01841: (全)年度值必须介于 -4713 和 9999 之间,且不为 0
SQL> insert into test_date values (to_date('0000-1-1 0:0:0', 'yyyy-mm-dd hh24:mi:ss'));
insert into test_date values (to_date('0000-1-1 0:0:0', 'yyyy-mm-dd hh24:mi:ss'))
                                      *
ERROR 位于第 1 行:
ORA-01841: (全)年度值必须介于 -4713 和 9999 之间,且不为 0
SQL> col dump_date format a80
SQL> select to_char(date_col, 'syyyy-mm-dd hh24:mi:ss'), dump(date_col) dump_date from test_date;
TO_CHAR(DATE_COL,'SY DUMP_DATE
-------------------- ---------------------------------------
 2000-01-01 00:00:00 Typ=12 Len=7: 120,100,1,1,1,1,1
 0001-01-01 00:00:00 Typ=12 Len=7: 100,101,1,1,1,1,1
-0001-01-01 00:00:00 Typ=12 Len=7: 100,99,1,1,1,1,1
-0101-01-01 00:00:00 Typ=12 Len=7: 99,99,1,1,1,1,1
-4712-01-01 00:00:00 Typ=12 Len=7: 53,88,1,1,1,1,1
 9999-12-31 23:59:59 Typ=12 Len=7: 199,199,12,31,24,60,60
 2004-12-15 13:56:19 Typ=12 Len=7: 120,104,12,15,14,57,20
已选择7行。
 
经由议定最后两条语句曾经可以看出Oracle的DATE范例的取值范畴是公元前4712年1月1日大公元9999年12月31日。而且依据日期的特定,要否则是公元1年,要否则是公元前1年,不会出现0年的情况。
日期范例长度是7,7个字节区分体现世纪、年、月、日、时、分和秒。
由于不会出现0的情况,月和日都是依照原值存储的,月的范畴是1~12,日的范畴是1~31。
由于时、分、秒都市出现0的情况,因此存储时采纳原值加1的体式款式。0时生活生计为1,13时生活生计为14,23时生活生计为24。分和秒的情况与小时雷同。小时的范畴是0~23,在数据库中以1~24生活生计。分和秒的范畴都是0~59,在数据库中以1~60生活生计。
年和世纪的情况相对比拟复杂,可分为公元前和公元后两种情况。由于最小的世纪的值是-47(公元前4712年),最年夜值是99(公元9999年)。为了防止负数的孕育发生发火,oracle把世纪加100生活生计在数据库中。公元2000年,世纪生活生计为120,公元9999年,世纪生活生计为199,公元前101年,世纪生活生计为99(100 (-1)),公元前4712年,世纪生活生计为53(100 (-47))。
注意,关于公元前1年,当然曾经是公元前了,但是体现世纪的前两位的值依然是0,因此,这时的生活生计的世纪的值依然是100。世纪的范畴是-47~99,生活生计的值是53~199。
年的生活生计与世纪的生活生计体式款式雷同,也把年的值加上100截至生活生计。关于公元2000年,年坚持为100,公元1年生活生计为101,公元2004年生活生计为104,公元9999年生活生计为199,公元前1年,生活生计为99(100 (-1)),公元前101年,生活生计为99(100 (-1)),公元前4712年生活生计为88(100 (-12))。关于公元前的年,生活生计的值老是小于便是100,关于公元后的年,生活生计的值老是年夜于便是100。年的范畴是0~99,生活生计的值是1~199。
注意:一样往常的世纪,都包括了100年,而关于0世纪,由于包括公元前和公元后两部分且不包括0年,因此包括了198年。
==============================================================
Oracle基本数据范例存储名堂浅析(三)——日期范例(二)
揭晓人:yangtingkun | 揭晓时分: 2004年十二月16日, 18:03
这篇文章描画TIMESTAMP范例的数据在Oracle中因此何种名堂寄存的。
上面经由议定一个例子截至剖析。
 
SQL> create table test_time (col_time timestamp);
表已创设。
SQL> insert into test_time values (to_timestamp('0001-1-1 0:0:0.0', 'syyyy-mm-dd hh24:mi:ss.ff'));
已创设 1 行。
SQL> insert into test_time values (to_timestamp('2000-1-1 0:0:0.0', 'syyyy-mm-dd hh24:mi:ss.ff'));
已创设 1 行。
SQL> insert into test_time values (to_timestamp('9999-12-31 23:59:59.999999', 'syyyy-mm-dd hh24:mi:ss.ff'));
已创设 1 行。
SQL> insert into test_time values (to_timestamp('-0001-1-1 0:0:0.0', 'syyyy-mm-dd hh24:mi:ss.ff'));
已创设 1 行。
SQL> insert into test_time values (to_timestamp('-0100-3-4 13:2:3.234015', 'syyyy-mm-dd hh24:mi:ss.ff'));
已创设 1 行。
SQL> insert into test_time values (systimestamp);
已创设 1 行。
SQL> insert into test_time values (to_timestamp('2000-1-1 0:0:0.123456789', 'syyyy-mm-dd hh24:mi:ss.ff9'));
已创设 1 行。
SQL> commit;
提交完成。
SQL> select to_char(col_time, 'syyyy-mm-dd hh24:mi:ss.ff9') time, dump(col_time) dump_time
  2  from test_time;
TIME                           DUMP_TIME
------------------------------ ----------------------------------------------------
 0001-01-01 00:00:00.000000000 Typ=180 Len=7: 100,101,1,1,1,1,1
 2000-01-01 00:00:00.000000000 Typ=180 Len=7: 120,100,1,1,1,1,1
 9999-12-31 23:59:59.999999000 Typ=180 Len=11: 199,199,12,31,24,60,60,59,154,198,24
-0001-01-01 00:00:00.000000000 Typ=180 Len=7: 100,99,1,1,1,1,1
-0100-03-04 13:02:03.234015000 Typ=180 Len=11: 99,100,3,4,14,3,4,13,242,201,24
 2004-12-15 16:14:52.738000000 Typ=180 Len=11: 120,104,12,15,17,15,53,43,252,252,128
 2000-01-01 00:00:00.123457000 Typ=180 Len=11: 120,100,1,1,1,1,1,7,91,205,232
已选择7行。
与DATE范例比拟可以发现,关于TIMESTAMP范例,若是不包括微秒信息或许微秒值为0,那么存储下场和DATE完全雷同。当微秒值为0时,Oracle为了浪费空间,不会生活生计微秒信息。
若是毫秒值不为0,Oracle把微秒值看成一个9位数的数字来生活生计。
比方999999000,生活生计为59,154,198,24。234015000生活生计为13,242,201,24。
SQL> select to_char(999999000, 'xxxxxxxxxx') from dual;
TO_CHAR(999
-----------
   3b9ac618
SQL> select to_number('3b', 'xxx') one, to_number('9a', 'xxx') two,
  2  to_number('c6', 'xxx') three, to_number('18', 'xxx') four from dual;
       ONE        TWO      THREE       FOUR
---------- ---------- ---------- ----------
        59        154        198         24
SQL> select to_char(234015000, 'xxxxxxxx') from dual;
TO_CHAR(2
---------
  df2c918
SQL> select to_number('d', 'xxx') one, to_number('f2', 'xxx') two,
  2  to_number('c9', 'xxx') three, to_number('18', 'xxx') four from dual;
       ONE        TWO      THREE       FOUR
---------- ---------- ---------- ----------
        13        242        201         24
 
别的,注意一点,不指定精度的情况下,TIMESTAMP默许取6位。长度凌驾6位,会四舍五入到6位。若是希望生活生计9位的TIMESTAMP,必须晓畅指定精度。
SQL> alter table test_time modify (col_time timestamp(9));
表已变动。
SQL> insert into test_time values (to_timestamp('2000-1-1 0:0:0.123456789', 'syyyy-mm-dd hh24:mi:ss.ff9'));
已创设 1 行。
SQL> select to_char(col_time, 'syyyy-mm-dd hh24:mi:ss.ff9') time, dump(col_time) dump_time
  2  from test_time;
TIME                           DUMP_TIME
------------------------------ ---------------------------------------------------
 0001-01-01 00:00:00.000000000 Typ=180 Len=7: 100,101,1,1,1,1,1
 2000-01-01 00:00:00.000000000 Typ=180 Len=7: 120,100,1,1,1,1,1
 9999-12-31 23:59:59.999999000 Typ=180 Len=11: 199,199,12,31,24,60,60,59,154,198,24
-0001-01-01 00:00:00.000000000 Typ=180 Len=7: 100,99,1,1,1,1,1
-0100-03-04 13:02:03.234015000 Typ=180 Len=11: 99,100,3,4,14,3,4,13,242,201,24
 2004-12-15 16:14:52.738000000 Typ=180 Len=11: 120,104,12,15,17,15,53,43,252,252,128
 2000-01-01 00:00:00.123457000 Typ=180 Len=11: 120,100,1,1,1,1,1,7,91,205,232
 2000-01-01 00:00:00.123456789 Typ=180 Len=11: 120,100,1,1,1,1,1,7,91,205,21
已选择8行。
==============================================================
Oracle基本数据范例存储名堂浅析(三)——日期范例(三)
揭晓人:yangtingkun | 揭晓时分: 2004年十二月17日, 17:00
若是间接在SQL语句中对SYSDATE或由TO_DATE函数生成日期截至DUMP把持,会发现掉掉的下场与DUMP数据库中生活生计的日期的下场纷歧样。
 
SQL> truncate table test_date;
表已截掉。
SQL> insert into test_date values (to_date('2004-12-17 16:42:42', 'syyyy-mm-dd hh24:mi:ss'));
已创设 1 行。
SQL> col dump_date format a65
SQL> select to_char(date_col, 'syyyy-mm-dd hh24:mi:ss') dat, dump(date_col) dump_date from test_date;
DAT                  DUMP_DATE
-------------------- ---------------------------------------------------------
 2004-12-17 16:42:42 Typ=12 Len=7: 120,104,12,17,17,43,43
SQL> select to_char(to_date('2004-12-17 16:42:42', 'syyyy-mm-dd hh24:mi:ss'), 'syyyy-mm-dd hh24:mi:ss') dat,
  2  dump(to_date('2004-12-17 16:42:42', 'syyyy-mm-dd hh24:mi:ss')) dump_date from dual;
DAT                  DUMP_DATE
-------------------- ---------------------------------------------------------
 2004-12-17 16:42:42 Typ=13 Len=8: 212,7,12,17,16,42,42,0
存储在数据库中的DATE范例是12,而间接在SQL中运用的DATE范例是13。而且二者的长度以及体现体式款式都不雷同。这两种范例的差异指出次要体今朝两点:一:时、分、秒的体现差异;二、世纪和年的体现差异。
SQL中运用DATE的时分秒没有采纳加1存储体式款式,而且原值存储。
SQL中运用DATE没有采纳世纪、年的体式款式坚持,而是采纳了按数值生活生计的体式款式。第一位体现低位,第二位体现高位。低位体现最年夜的值是255。如上面的例子中,212 7×256=2004。
SQL> select to_char(to_date('-2004-12-17 16:42:42', 'syyyy-mm-dd hh24:mi:ss'), 'syyyy-mm-dd hh24:mi:ss') dat,
  2  dump(to_date('-2004-12-17 16:42:42', 'syyyy-mm-dd hh24:mi:ss')) dump_date from dual;
DAT                  DUMP_DATE
-------------------- ---------------------------------------------------
-2004-12-17 16:42:42 Typ=13 Len=8: 44,248,12,17,16,42,42,0
SQL> select dump(to_date('-1-1-1', 'syyyy-mm-dd')) from dual;
DUMP(TO_DATE('-1-1-1','SYYYY-MM-D
---------------------------------
Typ=13 Len=8: 255,255,1,1,0,0,0,0
 
关于公元前的日期,Oracle从255,255脱手脱手生活生计。公元前的年的生活生计的值和对应的公元后的年的值相加的和是256,255。如上例中的公元2004年和公元前2004年的值相加:212 44=256,7 248=255。
SQL中DATE范例最后还网罗一个0,好像今朝没有运用。
==============================================================
Oracle基本数据范例存储名堂浅析(三)——日期范例(四)
揭晓人:yangtingkun | 揭晓时分: 2005年一月12日, 02:26
本文对TIMESTAMP WITH LOCAL TIME ZONE和TIMESTAMP WITH TIME ZONE范例的存储名堂截至约莫纰漏的剖析。
 
SQL> CREATE TABLE TEST_TIMESTAMP(TIME1 TIMESTAMP(9), TIME2 TIMESTAMP(6) WITH LOCAL TIME ZONE,
  2  TIME3 TIMESTAMP(4) WITH TIME ZONE);
表已创设。
SQL> INSERT INTO TEST_TIMESTAMP VALUES (SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP);
已创设 1 行。
SQL> SELECT * FROM TEST_TIMESTAMP;
TIME1
----------------------------------------------------
TIME2
----------------------------------------------------
TIME3
----------------------------------------------------
11-1月 -05 11.08.15.027000000 下战书
11-1月 -05 11.08.15.027000 下战书
11-1月 -05 11.08.15.0270 下战书 08:00
SQL> SELECT DUMP(TIME1, 16), DUMP(TIME2, 16), DUMP(TIME3, 16) FROM TEST_TIMESTAMP;
DUMP(TIME1,16)
-------------------------------------------------------------
DUMP(TIME2,16)
-------------------------------------------------------------
DUMP(TIME3,16)
-------------------------------------------------------------
Typ=180 Len=11: 78,69,1,b,18,9,10,1,9b,fc,c0
Typ=231 Len=11: 78,69,1,b,18,9,10,1,9b,fc,c0
Typ=181 Len=13: 78,69,1,b,10,9,10,1,9b,fc,c0,1c,3c
可以发现,若是客户端和数据库中的时区是对等的,那么TIMESTAMP和TIMESTAMP WITH LOCAL TIME ZONE存储的数据是完全一样的。
TIMESTAMP WITH TIME ZONE则略有差异,它生活生计的是0时区的时分,和所处的时区信息。
批改客户端主机的时区,由东8区( 8区)改为0时区。
SQL> INSERT INTO TEST_TIMESTAMP VALUES (SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP);
已创设 1 行。
批改客户端主机的时区,改为西5区(-5时区)。
SQL> INSERT INTO TEST_TIMESTAMP VALUES (SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP);
已创设 1 行。
批改客户端主机的时区,改为西12区(-12时区)。
SQL> INSERT INTO TEST_TIMESTAMP VALUES (SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP);
已创设 1 行。
批改客户端主机的时区,改为东13区( 13时区)。
SQL> INSERT INTO TEST_TIMESTAMP VALUES (SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP);
已创设 1 行。
批改客户端主机的时区,改为西3.5区(-3.5时区)。
SQL> INSERT INTO TEST_TIMESTAMP VALUES (SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP);
已创设 1 行。
批改客户端主机的时区,改为东9.5区( 9.5时区)。
SQL> INSERT INTO TEST_TIMESTAMP VALUES (SYSTIMESTAMP, SYSTIMESTAMP, SYSTIMESTAMP);
已创设 1 行。
SQL> COMMIT;
提交完成。
批改客户端主机的时区,改回东8区( 8时区)。
SQL> SELECT * FROM TEST_TIMESTAMP;
TIME1
-----------------------------------------------
TIME2
-----------------------------------------------
TIME3
-----------------------------------------------
11-1月 -05 11.08.15.027000000 下战书
11-1月 -05 11.08.15.027000 下战书
11-1月 -05 11.08.15.0270 下战书 08:00
11-1月 -05 03.11.43.746000000 下战书
11-1月 -05 11.11.43.746000 下战书
11-1月 -05 03.11.43.7460 下战书 00:00
11-1月 -05 10.14.08.987000000 上午
11-1月 -05 11.14.08.987000 下战书
11-1月 -05 10.14.08.9870 上午 -05:00
11-1月 -05 03.15.01.732000000 上午
11-1月 -05 11.15.01.732000 下战书
11-1月 -05 03.15.01.7320 上午 -12:00
12-1月 -05 04.20.21.522000000 上午
11-1月 -05 11.20.21.522000 下战书
12-1月 -05 04.20.21.5220 上午 13:00
11-1月 -05 02.15.16.567000000 下战书
12-1月 -05 01.45.16.567000 上午
11-1月 -05 02.15.16.5670 下战书 -03:30
12-1月 -05 03.16.54.992000000 上午
12-1月 -05 01.46.54.992000 上午
12-1月 -05 03.16.54.9920 上午 09:30
已选择7行。
SQL> SELECT DUMP(TIME1, 16), DUMP(TIME2, 16), DUMP(TIME3, 16) FROM TEST_TIMESTAMP;
DUMP(TIME1,16)
-------------------------------------------------------------
DUMP(TIME2,16)
-------------------------------------------------------------
DUMP(TIME3,16)
-------------------------------------------------------------
Typ=180 Len=11: 78,69,1,b,18,9,10,1,9b,fc,c0
Typ=231 Len=11: 78,69,1,b,18,9,10,1,9b,fc,c0
Typ=181 Len=13: 78,69,1,b,10,9,10,1,9b,fc,c0,1c,3c
Typ=180 Len=11: 78,69,1,b,10,c,2c,2c,77,e,80
Typ=231 Len=11: 78,69,1,b,18,c,2c,2c,77,e,80
Typ=181 Len=13: 78,69,1,b,10,c,2c,2c,77,e,80,14,3c
Typ=180 Len=11: 78,69,1,b,b,f,9,3a,d4,6c,c0
Typ=231 Len=11: 78,69,1,b,18,f,9,3a,d4,6c,c0
Typ=181 Len=13: 78,69,1,b,10,f,9,3a,d4,6c,c0,f,3c
Typ=180 Len=11: 78,69,1,b,4,10,2,2b,a1,6f,0
Typ=231 Len=11: 78,69,1,b,18,10,2,2b,a1,6f,0
Typ=181 Len=13: 78,69,1,b,10,10,2,2b,a1,6f,0,8,3c
Typ=180 Len=11: 78,69,1,c,5,15,16,1f,1d,16,80
Typ=231 Len=11: 78,69,1,b,18,15,16,1f,1d,16,80
Typ=181 Len=13: 78,69,1,b,10,15,16,1f,1d,16,80,21,3c
Typ=180 Len=11: 78,69,1,b,f,10,11,21,cb,bb,c0
Typ=231 Len=11: 78,69,1,c,2,2e,11,21,cb,bb,c0
Typ=181 Len=13: 78,69,1,b,12,2e,11,21,cb,bb,c0,11,1e
Typ=180 Len=11: 78,69,1,c,4,11,37,3b,20,b8,0
Typ=231 Len=11: 78,69,1,c,2,2f,37,3b,20,b8,0
Typ=181 Len=13: 78,69,1,b,12,2f,37,3b,20,b8,0,1d,5a
 
SQL> SELECT TO_NUMBER('1C', 'XXX'), TO_NUMBER('3C', 'XXX') FROM DUAL;
TO_NUMBER('1C','XXX') TO_NUMBER('3C','XXX')
--------------------- ---------------------
                   28                    60
SQL> SELECT TO_NUMBER('14', 'XXX'), TO_NUMBER('3C', 'XXX'), TO_NUMBER('143C', 'XXXXXXX') FROM DUAL;
TO_NUMBER('14','XXX') TO_NUMBER('3C','XXX')
--------------------- ---------------------
                   20                    60
SQL> SELECT TO_NUMBER('3C', 'XXX') , TO_NUMBER('1E', 'XXX'), TO_NUMBER('5A', 'XXX') FROM DUAL;
TO_NUMBER('3C','XXX') TO_NUMBER('1E','XXX') TO_NUMBER('5A','XXX')
--------------------- --------------------- -------------------
                   60                    30                  90
可以看出,批改时区会招致系统TIMESTAMP时分发生发火变化,但是关于TIMESTAMP WITH LOCAL TIME ZONE范例,老是将系统的时分转化到数据库管事器上时区的时分截至存储。
TIMESTAMP WITH TIME ZONE生活生计的是当前时分转化到0时区的对应的时分,并经由议定最后两位来生活生计时区信息。
第一位体现时区的小时部分。0时区用0x14体现。东n区在这个根本上加n,西n区在这个根本上减n。我们所处的东8区体现为0x1C。西5区体现为0xF。
第二位体现时区的分钟部分。典型典范是0x3C,即60分钟。关于东时区的半区,在这个根本上加上30分钟,若是是西时区,则减去30分钟。
==============================================================
Oracle基本数据范例存储名堂浅析(四)——ROWID范例(一)
揭晓人:yangtingkun | 揭晓时分: 2004年十二月21日, 19:14
Oracle的ROWID用来独一标识表中的一条纪录,是这条数据在数据库中寄存的物理地点。
Oracle的ROWID分为两种:物理ROWID和逻辑ROWID。索引构造表运用逻辑ROWID,其他范例的表运用物理ROWID。此中物理ROWID在Oracle的8版本中截至了扩展,Oracle7及以下版本运用束厄窄小ROWID,Oracle8及以上版本运用扩展ROWID。本文描画物理扩展ROWID,由于束厄窄小ROWID仅仅是为了兼容晚期版本,因此不做讨论。
SQL> create table test_rowid (id number, row_id rowid);
表已创设。
SQL> insert into test_rowid values (1, null);
已创设 1 行。
SQL> update test_rowid set row_id = rowid where id = 1;
已更新 1 行。
SQL> commit;
提交完成。
SQL> select rowid, row_id from test_rowid;
ROWID              ROW_ID
------------------ ------------------
AAABnRAAGAAAACWAAA AAABnRAAGAAAACWAAA
Oracle的物理扩展ROWID有18位,每位采纳64位编码,区分用A~Z、a~z、0~9、 、/共64个字符体现。A体现0,B体现1,……Z体现25,a体现26,……z体现51,0体现52,……,9体现61, 体现62,/体现63。
ROWID过细别离可以分为4部分。
1.OOOOOO:前6位体现DATA OBJECT NUMBER,将起转化位数字后完婚DBA_OBJECTS中的DATA_OBJECT_ID,可以确定表信息。
如上面例子中的DATA OBJECT NUMBER是AAABnR,转化位数字是1×64×64 +39×64 + 17。
SQL> select owner, object_name from dba_objects
  2  where data_object_id = 1*64*64 39*64 17;
OWNER                          OBJECT_NAME
------------------------------ -----------------------------
YANGTK                         TEST_ROWID
2.FFF:第7到9位体现相对表空间的数据文件号。
上面的例子中是AAG,体现数据文件6。
SQL> select file_name, tablespace_name from dba_data_files where relative_fno = 6;
FILE_NAME                                     TABLESPACE_NAME
--------------------------------------------- ---------------
E:ORACLEORADATATESTYANGTK01.DBF           YANGTK
3.BBBBBB:第10到15位体现这条纪录在数据文件中的第几个BLOCK中。
上面的例子是AAAACW,转化位数字是2×64+22,体现这条纪录在数据文件中的第150个BLOCK。
4.RRR:最后3位体现这条纪录是BLOCK中的第几条纪录。
上面的例子是AAA,体现第0条纪录(老是从0脱手脱手计数)。
SQL> alter system dump datafile 6 block 150;
系统已变动。
SQL> select row_id, dump(row_id, 16) dump_rowid from test_rowid;
ROW_ID             DUMP_ROWID
------------------ -------------------------------------------------
AAABnRAAGAAAACWAAA Typ=69 Len=10: 0,0,19,d1,1,80,0,96,0,0
 
找到对应的dump文件,可以发现范例的信息
AV女伶 2004-12-21 17:58:26.000
AV女伶 SESSION ID:(13.91) 2004-12-21 17:58:26.000
Start dump data blocks tsn: 6 file#: 6 minblk 150 maxblk 150
buffer tsn: 6 rdba: 0x01800096 (6/150)
scn: 0x0000.2e389c16 seq: 0x01 flg: 0x06 tail: 0x9c160601
frmt: 0x02 chkval: 0xc97d type: 0x06=trans data
Block header dump:  0x01800096
 Object id on Block? Y
 seg/obj: 0x19d1  csc: 0x00.2e389c0f  itc: 2  flg: O  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0003.009.00000057  0x0080004b.0042.56  --U-    1  fsc 0x0000.2e389c16
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
 
data_block_dump,data header at 0x651105c
===============
tsiz: 0x3fa0
hsiz: 0x14
pbl: 0x0651105c
bdba: 0x01800096
     76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
f搜索引擎优化=0x3f89
avsp=0x3f7b
tosp=0x3f7b
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x3f89
block_row_dump:
tab 0, row 0, @0x3f89
tl: 17 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [10]  00 00 19 d1 01 80 00 96 00 00
end_of_block_dump
End dump data blocks tsn: 6 file#: 6 minblk 150 maxblk 150
 
有时需求查看表的DUMP信息,但是很难精确定位表中数据脱手脱手于哪个BLOCK,依据ROWID中包括的信息就可以利便的找到肇端BLOCK。
上面约莫纰漏描画一下ROWID范例是若何存储的。
SQL> select row_id, dump(row_id, 16) dump_rowid from test_rowid;
ROW_ID             DUMP_ROWID
------------------ -------------------------------------------------
AAABnRAAGAAAACWAAA Typ=69 Len=10: 0,0,19,d1,1,80,0,96,0,0
前4位体现ROWID的前6位,也就是DATA_OBJECT_ID信息。数据以数值的名堂生活生计。
SQL> select to_number('19d1', 'xxxxxx') from dual;
TO_NUMBER('19D1','XXXXXX')
--------------------------
                      6609
SQL> select 1*64*64 39*64 17 from dual;
1*64*64 39*64 17
----------------
            6609
这里存在一个成绩,依据ROWID的取值范畴,OBJECT_DATA_ID最年夜的值是64的6次方,而依据DUMP,oracle只用了4位生活生计,因此取值范畴是256的4次方。
SQL> set numwid 12
SQL> select power(64, 6), power(256, 4), power(64, 6)/power(256, 4) from dual;
 POWER(64,6) POWER(256,4) POWER(64,6)/POWER(256,4)
------------ ------------ ------------------------
 68719476736   4294967296                       16
可见,OBJECT_DATA_ID的最年夜值是4294967296,当凌驾这个值时会出现重复的情况。(当然,现实中不年夜可以)。
后面4位比拟特别,是数据文件号和BLOCK数的“和”值构成。
数据文件的数值乘64后生活生计在5、6位上。
SQL> select to_number('0180', 'xxxx') from dual;
TO_NUMBER('0180','XXXX')
------------------------
                     384
SQL> select 6*64 from dual;
        6*64
------------
         384
同时,6位BLOCK的值,也生活生计在这4位上,并与数据文件转存下场相加。依然因此数字名堂寄存。
SQL> select to_number('96', 'xxx') from dual;
TO_NUMBER('96','XXX')
---------------------
                  150
SQL> select 2*64 22 from dual;
   2*64 22
----------
       150
由于采纳两位生活生计数据文件的值,且最小单位是64,因此,ROWID中可以生活生计的数据文件数是1024,凌驾1024会构成ROWID的重复。
SQL> select 256*256/64 from dual;
256*256/64
----------
      1024
由于BLOCK的值和数据文件共用这4位,因此BLOCK的第3位最年夜值应小于64,如许才干担保ROWID的不重复。因此BLOCK值的最年夜值应该是4194304。
SQL> select 64*256*256 from dual;
64*256*256
----------
   4194304
最后两位生活生计BLOCK中纪录的值。这个值的最年夜值是65536。
SQL> select 256*256 from dual;
   256*256
----------
     65536
 
上面看一个例子,Oracle是若何将相对文件号和BLOCK号“共享”第5、6字节的。
SQL> select blocks from user_segments where segment_name = 'TEST1';
    BLOCKS
----------
     86016
SQL> select max(rowid), dump(max(rowid)) dump_rowid from test1;
MAX(ROWID)         DUMP_ROWID
------------------ -------------------------------------------
AAABy AAJAAAU5EAAM Typ=69 Len=10: 0,0,28,190,2,65,78,68,0,12
SQL> select dbms_rowid.rowid_relative_fno('AAABy AAJAAAU5EAAM') fno,
  2  dbms_rowid.rowid_block_number('AAABy AAJAAAU5EAAM') block_num from dual;
       FNO  BLOCK_NUM
---------- ----------
         9      85572
SQL> select 9*64, 2*256 65 from dual;
      9*64   2*256 65
---------- ----------
       576        577
SQL> select 1*256*256 78*256 68 from dual;
1*256*256 78*256 68
-------------------
              85572
可以看到,5、6为的值除以64掉掉的商是相对文件号,余数是BLOCK号的高位,乘以65536后加上低两位才是BLOCK号。
==============================================================
Oracle基本数据范例存储名堂浅析(四)——ROWID范例(二)
揭晓人:yangtingkun | 揭晓时分: 2004年十二月22日, 23:52
Oracle的文档上没有介绍逻辑ROWID的编码法则,而且经由议定DUMP的下场也很难反推出编码法则。因此,本文只约莫纰漏讨论一下逻辑ROWID的存储。
上面来看例子。
SQL> create table test_index (id number primary key, name varchar2(20)) organization index;
表已创设。
SQL> insert into test_index values (1, 'a');
已创设 1 行。
SQL> commit;
提交完成。
SQL> col dump_rowid format a60
SQL> select rowid, dump(rowid) dump_rowid from test_index;
ROWID                       DUMP_ROWID
--------------------------- ----------------------------------------
*BAFAB4wCwQL                Typ=208 Len=10: 2,4,1,64,7,140,2,193,2,254
逻辑ROWID的DUMP下场前两位都是2和4,最月朔位都是254,(我还没有发现其他的情况),由于逻辑ROWID和主键的值有关,以是长度是不定的,因此应该是用来体现脱手脱手和完毕的。
第3、4位和物理ROWID一样,体现的是相对表空间的数据文件号乘以64的值。
第5、6位体现这条纪录在数据文件的第几个BLOCK中。
从第7位脱手脱手到DUMP下场的倒数第二位,体现主键的值。首先是主键中第一个字段的长度,这里是2,然后是主键的值,由于是NUMBER范例,因此193,2体现数值1。若是是多个字段构成的主键,第一个字段之后是第二个字段的长度,然后是第二个字段的值……。
SQL> select (1*256 64)/64 from dual;
(1*256 64)/64
-------------
            5
SQL> select 7*256 140 from dual;
 7*256 140
----------
      1932
SQL> alter system dump datafile 5 block 1932;
系统已变动。
找到响应的dump文件,可以发现刚刚拔出的纪录。
Dump file f:oracleadmintest4udumptest4_ora_3828.trc
Thu Dec 23 00:17:53 2004
ORACLE V9.2.0.4.0 - Production vsnsta=0
vsnsql=12 vsnxtr=3
Windows 2000 Version 5.1 Service Pack 1, CPU type 586
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Windows 2000 Version 5.1 Service Pack 1, CPU type 586
Instance name: test4
Redo thread mounted by this instance: 1
Oracle process number: 9
Windows thread id: 3828, image: ORACLE.EXE
AV女伶 2004-12-23 00:17:53.361
AV女伶 SESSION ID:(8.82) 2004-12-23 00:17:53.301
Start dump data blocks tsn: 5 file#: 5 minblk 1932 maxblk 1932
buffer tsn: 5 rdba: 0x0140078c (5/1932)
scn: 0x0000.00e9f122 seq: 0x01 flg: 0x02 tail: 0xf1220601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump:  0x0140078c
 Object id on Block? Y
 seg/obj: 0x1e48  csc: 0x00.e9f113  itc: 2  flg: E  typ: 2 - INDEX
     brn: 0  bdba: 0x1400789 ver: 0x01
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x02   0x0005.008.000000e7  0x00800226.005c.24  --U-    1  fsc 0x0000.00e9f122
 
Leaf block dump
===============
header address 71963236=0x44a1264
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x90: opcode=0: iot flags=I-- is converted=Y
kdxconco 1
kdxcosdc 0
kdxconro 1
kdxcofbo 38=0x26
kdxcofeo 8026=0x1f5a
kdxcoavs 7988
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8036
row#0[8026] flag: K----, lock: 2
col 0; len 2; (2):  c1 02
tl: 5 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 1]
Dump of memory from 0x044A31C7 to 0x044A31C8
44A31C0          61010100                        [...a]       
----- end of leaf block dump -----
End dump data blocks tsn: 5 file#: 5 minblk 1932 maxblk 1932
可以看到,依据DUMP下场的3、4、5、6位可以定位纪录的物理位置。
需求注意的是,索引构造表以主键的顺序存储数据,因此拔出、更新和删除数据都可以构成一条纪录的物理位置发生发火变化,这时经由议定ROWID中的DATAFILE和BLOCK的信息可以就无法精确定位到纪录的物理位置。当依据逻辑ROWID访问索引构造表时,首先会依据DATAFILE和BLOCK信息去找到响应的BLOCK,搜查数据能否在这个BLOCK中,若是不在,就经由议定逻辑ROWID中的主键信息去经由议定索引扫描,找到这条纪录。这就是Oracle文档在提到的physical guess。
上面看一个由字符串和日期构成连合主键的例子。
SQL> create table test_index2 (id char(4), time date,
  2  constraint pk_test_index2 primary key (id, time)) organization index;
表已创设。
SQL> insert into test_index2 values ('1', sysdate);
已创设 1 行。
SQL> col dump_rowid format a75
SQL> select rowid, dump(rowid) dump_rowid from test_index2;
ROWID                        DUMP_ROWID
---------------------------- ------------------------------------------------------------------
*BAFAB5QEMSAgIAd4aAwXASMT/g  Typ=208 Len=20: 2,4,1,64,7,148,4,49,32,32,32,7,120,104,12,23,1,35,19,254
可以看出,第7位是字段id的长度4,然后是字符串1和三个空格的ASCII码,这是字符串的存储名堂,后面跟着的7是字段time长度,后面七位是日期的存储名堂。在逻辑ROWID中,数值、字符和日期范例的存储名堂都和它们本人的存储名堂对等,这里不在赘述。
一样往常情况下,运用一位来体现长度,但是若是长度凌驾了127(16进制DUMP的下场是7F),则长度脱手脱手用两位体现。第一位以8扫尾,这个8只是标识位,表明长度字段今朝由两位来体现。比方长度128体现位8080,而支持的最年夜值3800体现为8ED8。
==============================================================
Oracle基本数据范例存储名堂浅析(五)——RAW范例
揭晓人:yangtingkun | 揭晓时分: 2004年十二月23日, 15:20
和其他数据范例比拟,RAW范例的存储显得直观多了,它和SELECT时数据展示的值完全一样。(SELECT时是依照16进制展示的)
 
SQL> create table test_raw (id number, raw_date raw(10));
表已创设。
SQL> insert into test_raw values (1, hextoraw('ff'));
已创设 1 行。
SQL> drop table test_raw;
表已扔掉。
SQL> create table test_raw (raw_col raw(10));
表已创设。
SQL> insert into test_raw values (hextoraw('ff'));
已创设 1 行。
SQL> insert into test_raw values (hextoraw('0'));
已创设 1 行。
SQL> insert into test_raw values (hextoraw('23fc'));
已创设 1 行。
SQL> insert into test_raw values (hextoraw('fffffffffff'));
已创设 1 行。
SQL> insert into test_raw values (hextoraw('ffffffffffffffffffff'));
已创设 1 行。
SQL> insert into test_raw values (utl_raw.cast_to_raw('051'));
已创设 1 行。
SQL> select raw_col, dump(raw_col, 16) dump_raw from test_raw;
RAW_COL              DUMP_RAW
-------------------- -----------------------------------------------
FF                   Typ=23 Len=1: ff
00                   Typ=23 Len=1: 0
23FC                 Typ=23 Len=2: 23,fc
0FFFFFFFFFFF         Typ=23 Len=6: f,ff,ff,ff,ff,ff
FFFFFFFFFFFFFFFFFFFF Typ=23 Len=10: ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
303531               Typ=23 Len=3: 30,35,31
已选择6行。
RAW范例的存储很约莫纰漏,比拟字段的盘诘下场和DUMP的下场就了如指掌了。
需求注意的是,两种转化为RAW的函数之间的差异。当运用HEXTORAW时,会把字符串中数据看成16进制数。而运用UTL_RAW.CAST_TO_RAW时,间接把字符串中每个字符的ASCII码寄存到RAW范例的字段中。
SQL> insert into test_raw values ('gg');
insert into test_raw values ('gg')
                             *
ERROR 位于第 1 行:
ORA-01465: 有用的十六进制数字
SQL> insert into test_raw values (hextoraw('gg'));
insert into test_raw values (hextoraw('gg'))
                                      *
ERROR 位于第 1 行:
ORA-01465: 有用的十六进制数字
SQL> insert into test_raw values (utl_raw.cast_to_raw('gg'));
已创设 1 行。
SQL> select raw_col, dump(raw_col, 16) dump_raw from test_raw;
RAW_COL              DUMP_RAW
-------------------- ----------------------------------------------
FF                   Typ=23 Len=1: ff
00                   Typ=23 Len=1: 0
23FC                 Typ=23 Len=2: 23,fc
6767                 Typ=23 Len=2: 67,67
0FFFFFFFFFFF         Typ=23 Len=6: f,ff,ff,ff,ff,ff
FFFFFFFFFFFFFFFFFFFF Typ=23 Len=10: ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
303531               Typ=23 Len=3: 30,35,31
已选择7行。

版权声明: 原创作品,允许转载,转载时请务必以超链接体式款式标明文章 原始来由 、作者信息和本声明。否则将清查法则责任。

转载于:https://www.cnblogs.com/zgqjymx/archive/2011/03/07/1976412.html

Oracle基本数据范例存储名堂浅析相关推荐

  1. Oracle根底数据标准存储名目浅析(三)——日期标准(三)

    来历:yangtingkun.itpub.net 倘若间接在SQL语句中对SYSDATE或由TO_DATE函数生成日期进行DUMP操纵,会创造掉掉的成绩与DUMP数据库中保管的日期的成绩不一样. SQ ...

  2. Oracle基本数据标准存储样式浅析(二)——数字标准

    前导发端:yangtingkun.itpub.net 这篇文章重要描述NUMBER标准的数据和若安在数据库中存储的. Oracle的NUMBER标准最多由三个部门构成,这三个部门分袂是最高位表示位.数 ...

  3. oracle查看表和索引碎片,Oracle 表空间索引存储与碎片检查

    Oracle 表空间索引存储与碎片检查 Oracle 表空间索引存储检查,Oracle 表空间索引碎片查看,包括查看系统表中的用户索引.索引的存储情况检查.索引的选择性.确定索引的实际碎片. 1.查看 ...

  4. Oracle数据类型及存储方式——字符类型篇

    注:这篇文章绝大部分都摘抄于袁光东先生的  <<oracle小组学习笔记>>. 下面会对各种字符类型作详细解释. 一. char 类型 oracle 可以定义1个char(n) ...

  5. Oracle 数据类型及存储方式

    Oracle 数据类型及存储方式  袁光东 原创  概述  通过实例,全面而深入的分析oralce的基本数据类型及它们的存储方式.以ORACLE 10G为基础,介绍oralce 10g引入的新的数据类 ...

  6. Oracle 数据类型及存储方式(袁光东 原创)

    概述 通过实例,全面而深入的分析oralce 10G的基本数据类型及它们的存储方式.从实用和优化的角度出发,讨论每种数据类型的特点.从这里开始oracle之旅! 第一部份 字符类型 §1.1 char ...

  7. oracle实验报告2:: Oracle数据库物理存储结构管理(含实验小结)

    目录 实验目的 实验设备及器材 实验内容 实验步骤 实验过程 实验小结 实验目的 1.熟悉Oracle数据库物理存储结构: 2.掌握Oracle数据库数据文件的管理: 3.掌握Oracle数据库控制文 ...

  8. oracle asm 缺省用户,oracle asm自动存储使用及管理说明(下)

    接上篇:oracle asm自动存储使用及管理说明(上) 六.文件及tempate 1.数据文件命名含义 SQL> select file_name from dba_data_files; F ...

  9. oracle存储多少条数据类型,Oracle目前可以存储极大的对象,这是因为它引入了四种新的数据类型。其中哪一种大对象数据类型在数...

    Oracle目前可以存储极大的对象,这是因为它引入了四种新的数据类型.其中哪一种大对象数据类型在数 更多相关问题 谈谈我国幼儿教师的基本权利和义务. 请帮忙给出正确答案和分析,谢谢! 监察机关在办理监 ...

  10. Oracle 19c rac 存储迁移

    Oracle 19c rac 存储迁移 一.概述 二.openfiler添加新存储硬盘 三.操作系统挂载共享存储 四.配置udev 五.确认磁盘可用性 六.备份ocr和votedisk 七.迁移ocr ...

最新文章

  1. 前后端分离的思考与实践(三)
  2. 【深度学习入门到精通系列】医学图像预处理—伽马变化代码
  3. PHP json_encode 只支持utf8编码
  4. 腾讯员工晒出薪资:真实 985 毕业薪资,大家看我还有救吗?网友:日薪?
  5. 【大讲堂讲师专访】张甦:数据库选型需因地制宜,MongoDB与MySQL绝非替代
  6. c++ 线程池_JAVA并发编程:线程池ThreadPoolExecutor源码分析
  7. r语言折线图_R语言基础入门视频教程——语法篇(完结)
  8. 【渝粤教育】广东开放大学 建筑设备 形成性考核 (33)
  9. PHP中Trait详解及其应用
  10. ImportError: No module named rospy
  11. 用Scratch制作血量条的方法+源码
  12. 怎么删除远程桌面连接IP记录 删除连接信息
  13. java 手机号码归属地_Java获取手机号码归属地
  14. 5s管理推进的三个阶段及三大实施原则
  15. 跨国企业如何更好地从云革命中获益?
  16. 高通8953 Android 9.0 在user模式下使用fastboot烧录
  17. Spring Boot默认异常处理BasicErrorController源码解读
  18. 解决Git push提交时Permission denied(publickey).Could not read from remote...的问题
  19. Python——列表的方法
  20. Python大学计算机程序设计-通讯录管理系统

热门文章

  1. 【学习笔记】n皇后问题的解决方法+改进代码(回溯递归)
  2. java 长整型long_C语言和java 长整型为何打印不同?
  3. cydia无法安装卸载插件_【初识太极】CAD卸载不干净无法重新安装怎么办?
  4. python数值运算函数代码_Python如何计算列表中所有数字的乘积?(代码示例)
  5. html图表实现,用 Flotr2 实现的 HTML5 图表
  6. 算法:翻转链表 Reverse Linked List 三种方法实现,迭代解决人类思维,递归解决机器思维 reverse node
  7. 基于PlayTennis数据集的决策树决策分析
  8. c语言山东科技大学答案oj,山东科技大学oj部分题目记答案.doc
  9. 6Jordan标准型的变换与应用
  10. 个税倒推收入的计算器_手把手教你做个税计算器(1)