oracle数据存储类型,oracle数据类型存储结构

目标:

在oracle服务中确认数据类型的内部构造

解释数据类型在内部是如何存储的

内部存储知识

能更好的解释和分析块dumps

某些崩溃诊断必须的技能

帮助客户分析各种存储问题

是明白内部事务的必须步骤

oracle数据类型

数据类型包含:

内置数据类型

用户自定义数据类型

结构型

对象类型

聚合型

VARRAYS

嵌套表

引用类型(引用对象类型)

注意的是,oracle为程序提供了很多种数据类型,例如

数字格式的:number,integer,float,decimal

字符格式的:char,charz,string,varchar

内部数据类型从内部向外部自动的由oracle来转换.

内置数据类型

char,nchar,varchar2,nvarchar2

number

raw

long,long raw

date

datetime以及时间间隔类型

clob,blob,nclob,bfile

rowid,urowid

列中的数据取决于列的数据类型,但是数据类型并不是存储列数据的块中,本章以及后续课程将使用sql dump函数.范例中列的名字为TYP,关联的内部代码是各种数据类型,内部代码存储在数据字典中,在表col$的列type#下.

char和varchar2

字符类型数据通常是以数据库的字符集(单字节)存储的

char

固定长度的字符串,最多2000字符;

内部代码:96

varchar2

浮动长度字符串,最多4000字符

内部代码:1

为了能识别dump的输出文件,必须要知道他们存储的代码页.

char

在char类型的列中,所有的空字节被空格(代码32)填充

长度固定

由于char类型代码为96,长度固定,因此很容易分辨出那些是用来填充的空格

varchar2

varchar2列中,将不用空格填充.

长度不固定

nchar和nvarchar2

字符数据也可以使用国家字符集(多字节)设置存储

nchar

固定长度,最多2000字节

内部代码:96

nvarchar2

浮动长度,最多4000字节

内部代码:1

number

数字类型内部存储是一个字节的变长阿拉伯数字数组

数字类型有以下格式

< [length]>,sign bit/expornent,digit1,digit2,...,digit20

内部代码:2

注意的是,number和float有同样的内部特性.

指数类型

指数字节包含三个部分:

符号位:是整个字节的最高位(128)

如果是0,则数字是负数

如果是1,则数字是正数或者0

偏移量:总是65

指数:

范围为-65到62

标示该数字100为基础的科学记数法

如果指数是200=128+65+7,那么指数就是7,因此数据应该是大于100的7次方

如果一个数字是服侍,指数也同样的计算,但是要从255翻转,例如,一个指数为7的负数的计算是:-(125+65+7)=-(200)=255-200=77

偏移量使得负数的指数不需要使用别的字节来作为指数标志

如果第一个字节大于128,那么数字是正的:

exponent=first byte 128 -65=first bytes193

如果第一个字节小于128,那么数字是负的:

exponent=(255-first byte)-128-65=62-first byte

digits

大部分数字的最高位是digit1

使用100作为基数(每一个数字是0-99之间)

对于正数:

对于每个digit使用进位(1…100)

对于负数:

不是使用进位,而是从101减

基数标志102(0×66)是最后的

数据库的进位中是没有0的,0标示数据结束.虽然现在该规则已经废除,但是为了兼容,还是保留.现在oracle通过计算长度来知道数据的结束.

存储是基于矢量对照语法的.从左边开始,比较数据的大小直到:

一个部分不同,在这种情况下,最低的字节决定最小数字

一个数据已经完成,在这种情况下,这个是两个数字中的最小的.

所有的数据都比较完成,在这种情况下,两个数字相等

负数从101开始存储,因此比较下面的数字:

4=<193,5>,3=<193,4>比较这些字节,+4大于+3.

负数-4和-3.指数必须是62,如果值不是从101开始,则可能-4=<62,5>并且-3=<62,4>,这个时候,-4比-3大,显然是错误的.但是从101开始以后,数字就变成了-4=<62,97>并且-3=<62,98>.现在-3是比-4大的.

字节102附加在负数的后面,保证他们排序的正确性.比较数字-100<61,100,102>和-115<61,100,86,102>如果102不在这里,那么<61,100>和<61,100,86>将得到错误的结果,-100比-115小.

正数的例子:

因为数字是基于100的,因此最大的数字是99.指数从-65到62,因此,oracle的number的范围为:1*100(-65)=1*10(-120)到99*100(62)+99*100(61)... 无限接近1*10^(126)

但是,因为最大的精度是38,oracle将对超出精度的数据进行round操作.如果数字的字节数超过21,oracle就会报溢出

16进制也包括在这里面,因为在块dump中是一样的表现的

要注意第二个字节是如何增加和减少的,数字是基于100的.

正数的解读

数字为正数,第一个字节必须大于128(0×80)

第一步:指数=第一个字节-193

第二步:每一个其他的数字都减1

第三步:从基于100的指数转换到基于10的指数

每一个结果通过100^(EXP-N)其中

EXP是第一步中得到的指数

N是数字的位置的顺序号(最高位的N=0)

第四步:将所有的值相加

负数的解读

数字为负数,第一个字节必须小于128(0×80)

第一步:指数=62-first bytes

第二步:每一个数字被101减

第三步:将基数从100转换为10

每一个数字乘以100^(EXP-N)这里

EXP是第一步中的指数值

N是数字位置顺序值(最高位为0)

第四部:确认尾巴上的102已经抛弃

第五步:将所有的值相加

如果数字标示超过21字节,则最后的102不被要求,oracle不会使用22字节来标示的.oracle将自己会考虑所有的字节.

long

最大2GB大小的变长字符串

在数据库字符集和用户session字符集间自动转换(基于参数NLS_LANG的设置)

永远是内嵌存储

内部代码:8

推荐将long类型转换为lob类型

long列在表中是内嵌存储的.因此最好是最后一个列(性能的因素).但是用户还是可以在任何顺序指定long列的,但是oracle会自己在数据字典中组织数据,将long放到最后.因此在表COL$中,COL#是用户创的列的顺序,SEGCOL#是真实的存储顺序.

如果用户在创建了表以后,通过alert命令给表增加了列,则long列不会被存储在最后.oracle会自己算出重排数据的代价,并且将决定权交给dba.

RAW和long

raw二进制数据长度浮动,最多2000字节

内部代码:23

long raw

raw二进制数据浮动长度,最多2GB

内部代码24

在用户字符集和数据库字符集之间无法进行自动转换.

推荐使用lob列来代替long raw列

long raw列数据也是内嵌存储在表中的

raw和long raw是二进制内容,因此不需要转换为可打印的

例如,v$sqlarea是一个含有raw类型的列ADDRESS,注意,在sql层不会进行数据内容转换的.

date

date存储是固定的7个字节,世纪,年,月,日时分秒各占一个字节

开始的两个字节存储世纪和年的基数是100

接下来的两个字节是月和年(没有加任何数字的)

最后三个字节是时(24小时制),分,秒(分别都加1了)

如果是作块的dump,要记得将数字从16进制转换为10进制.

有另外一个时间类型,内部代码13,有8个字节并且是被SYSDATE使用的

datetimes和intervals

在816中引入的新的数据类型

这些类型被称之为datatimes和intervals

datetime数据类型提供一个点的时间的信息

一个intereval行提供的是两个不同点的时间之间的信息

816中新的datetime类型:

TIME

TIME WITH TIME ZONE

TIMESTAMP

TIMESTAMP WITH TIME ZONE

TIMESTAMP WITH LOCAL TIME ZONE

816中新的interval类型:

INTERVAL YEAR TO MONTH

INTERVAL DAY TO SECOND

这些新的数据类型在816中并没有正式发布,因此是不被支持的,默认也是不可见的,向使用他们,必须设置事件:

event=”10406 trace name context forever”

event=”10407 trace name context forever”

time

该类型提供关于小时,分钟以及秒的9个数字精度的事件信息

固定长度是7字节数组

前三个字节是HH24,MI,SS(这三个都加过1的)

后四个字节是秒使用的(乘以10^9然后以16进制存储)

内部代码:178

假定一个time列有值为:03:50:30.123456789 PM

那么dump出来的是Type=178 Len=7 16,51,31,7,91,205,21

他们存储的是:

小时:16-1=15

分钟:51-1=50

秒:31-1=30

秒的精度部分  01 5B CD 15->123456789

也就是0.123456789秒

time with time zone

该类型提供关于小时,分,秒以及9个精度秒小数部分,时区小时和时区分钟

固定的是9个字节的数组

开始的三个是HH24,MI,SS(每个都加了1)

后面四个是秒

最后两个是:

时区小时(加20)

时区分钟(加60)

内部代码:179

timestamp

该类型提供关于年,月,日,小时,分钟以及秒以及9位秒小数精度的信息

固定11字节长度数组

开始7个和date类型相同

最后4个是秒的精度

内部代码:180

timestamp with time zone

提供关于年,月,日,时汾秒以及9位秒小数精度,时区小时和时区分钟

固定13字节长度

开始7个和date一样

然后4个是秒的精度

最后两个是时区小时和时区分钟

内部代码:181

timestamp with local time zone

提供年,月,日,小时,分钟和秒以及9位秒精度的信息的时间类型

固定11字节数组

开始7个和date一样

后面4个是秒的精度

列以session的时区作为时区

内部代码:231

interval year to month

提供两个时间点关于年和月的不同的信息

固定5个字节长度

四个字节表示年(加上0×80000000)

一个字节表示月(加上60)

偏移量加上是为了保证存储的是正数

内部代码:182

interval day to second

提供两个时间点不同的日,分以及秒

固定11个字节

前四个表示日(加上0×80000000)

小时,分,秒个用一个字节(加上60)

四个字节表示秒的精度(加上0×80000000)

偏移量是为了保证值是正数

内部代码:183

sysdate

内部类型

固定8个字节长度

世纪,年

月,日

小时,分,苗

未使用的

内部代码:13

虽然SYSDATE是一个内部类型,并且不能被用于用户自己定义的列,但是在数据字典中用的很多,例如v$LOG,下面的查询可可解释SYSDATE的值

select dump(sysdate) from dual;

前面两个是存储的年,并且是平台有关的顺序的.我们称之为AA和BB

在Sun上

如果AA<128 YYYY=AA*256+BB

如果AA>128 YYYY=(256-AA)*256+BB

rowid

是表中行记录的唯一的

三种格式:

受限的短格式

6个字节的16进制字符串

DBA+Row(2字节)

扩展格式

10字节16进制字符串

Object ID(4字节)+DBA+Row(2字节)

普通的Rowid

短格式一般用在短以及过年包含了行所属的情况,例如行指针,非分区表上的普通索引以及分区表上的本地索引.

长格式包含对象号码,附加的表空间关联DBA这些是用来标示唯一行的.通常用在全局索引和分区表中.他们是符合DTYBRI类型的,并且用在用户自定义的rowid列中.

通用rowid,在8i中被引入,有三个子类型:物理的,逻辑的以及远程的,内部代码是208

urowid

在以下两种情况下标示行的逻辑地址

索引组织表

外部表

最大3950个字节的16进制字符串

三种格式

物理

逻辑的

远程

内部代码:208

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值