rowid,mysql有没有rowid

http://www.itjxue.com  2023-01-04 15:45  来源:未知  点击次数: 

Oracle数据库中rowid什么作用?

ROWID是数据的详细地址,通过rowid,oracle可以快速的定位某行具体的数据的位置。

ROWID可以分为物理rowid和逻辑rowid两种。普通的堆表中的rowid是物理rowid,索引组织表(IOT)的rowid是逻辑rowid。oracle提供了一种urowid的数据类型,同时支持物理和逻辑rowid。

物理rowid又分为扩展rowid(extended rowid)和限制rowid(restricted rowid)两种格式。限制rowid主要是oracle7以前的rowid格式,现在已经不再使用,保留该类型只是为了兼容性。

1.创建一临时表

create table test_rowid (id number, row_id rowid);

2.插入一行记录

insert into test_rowid values(1,null);

3.修改刚插入的记录

update test_rowid set row_id = rowid where id = 1;

4.查看rowid

select rowid,row_id from test_rowid;

oracle中rowid和rownumber的区别

rownum和rowid都是伪列,但是两者的根本是不同的,rownum是根据sql查询出的结果给每行分配一个逻辑编号,所以你的sql不同也就会导致最终rownum不同,但是rowid是物理结构上的,在每条记录insert到数据库中时,都会有一个唯一的物理记录

例如

AAAMgzAAEAAAAAgAAB

7499

ALLEN

SALESMAN

7698

1981/2/20

1600.00

300.00

30

这里的AAAMgzAAEAAAAAgAAB物理位置对应了这条记录,这个记录是不会随着sql的改变而改变。

因此,这就导致了他们的使用场景不同了,通常在sql分页时或是查找某一范围内的记录时,我们会使用rownum。

1、rownum

例如:

查找2到10范围内的记录(这里包括2和10的记录)

select

*

from

(select

rownum

rn,

a.*

from

emp

a)

t

where

t.rn

between

2

and

10;

查找前三名的记录

select

*

from

emp

a

where

rownum

3;这里我们要注意,直接用rownum查找的范围必须要包含1;因为rownum是从1开始记录的,当然你可以把rownum查出来后放在一个虚表中作为这个虚表的字段再根据条件查询。

例如:

select

*

from

(select

rownum

rn,

a.*

from

emp

a)

t

where

t.rn

2;这就可以了

2、rowid

我们在处理一张表中重复记录时经常用到他,当然你也可以用一个很原始的方法,就是将有重复记录的表中的数据导到另外一张表中,最后再倒回去。

SQLcreate

table

stu_tmp

as

select

distinct*

from

stu;

SQLtruncate

table

sut;

//清空表记录

SQLinsert

into

stu

select

*

from

stu_tmp;

//将临时表中的数据添加回原表但是要是stu的表数据是百万级或是更大的千万级的,那这样的方法显然是不明智的,因此我们可以根据rowid来处理,rowid具有唯一性,查询时效率是很高的,

例如,学生表中的姓名会有重复的情况,但是学生的学号是不会重复的,如果我们要删除学生表中姓名重复只留学号最大的学生的记录,怎么办呢?

delete

from

stu

a

where

rowid

not

in

(select

max(rowid)

from

stu

b

where

a.name

=

b.name

and

a.stno

b.stno);

这样就可以了。

"oracle"中rowid怎么用?

ROWID是一种数据类型,它使用基于64为编码的18个字符来唯一标识一条记录物理位置的一个ID,类似于Java中一个对象的哈希码,都是为了唯一标识对应对象的物理位置,需要注意的是ROWID虽然可以在表中进行查询,但是其值并未存储在表中,所以不支持增删改操作,下面看个例子:

[html]?view plain?copy

SELECT?ROWNUM,ROWID,empno,ename,job?FROM?emp?WHERE?ROWNUM?=?5;

结果如下:

可以看到ROWID确实由18个字符组成,组成结构如下:

数据对象编号 ? ?文件编号 ? ?块编号 ? ?行编号 ?

OOOOOO ? ?FFF ? ?BBBBBB ? ?RRR ?

至于ROWID的作用,由于ROWID用来唯一标识表中数据的唯一性,所以可以利用这个特性去除重复,举个例子,首先运行下述两行代码:

[html]?view plain?copy

CREATE?TABLE?dept_bak?AS?SELECT?*?FROM?dept;

INSERT?INTO?dept_bak?SELECT?*?FROM?dept;

得到一个如下的数据库表

很明显,数据有重复的,但是ROWID肯定不会重复的,那么就可以利用这个特性去重,简单示例代码如下:

[html]?view plain?copy

DELETE?FROM?dept_bak?WHERE?ROWID?NOT?IN(?SELECT?MIN(ROWID)?FROM?dept_bak?GROUP?BY?DEPTNO);

说说Oracle的rowid

在Oracle中rowid唯一标识每条记录所在的位置 它作为一个伪列在查询中出现

select rowid id

from test_table

where rownum= ;

ROWID????????????????????? ID

AAAVcbAAPAAAAALAAA?????????

AAAVcbAAPAAAAALAAB?????????

AAAVcbAAPAAAAALAAC?????????

AAAVcbAAPAAAAALAAD?????????

AAAVcbAAPAAAAALAAE?????????

AAAVcbAAPAAAAALAAF?????????

AAAVcbAAPAAAAALAAG?????????

AAAVcbAAPAAAAALAAH?????????

AAAVcbAAPAAAAALAAI?????????

AAAVcbAAPAAAAALAAJ????????

rowid是由 个字符组成分 个部分 分别是

个字符的对象编号 个字符的文件号 个字符的块编号 个字符的行编号

每一个字符的取值范围以及对应的数值是

| A|? |??? | a| |??? | | |

| B|? |??? | b| |??? | | |

| C|? |??? | c| |??? | | |

| D|? |??? | d| |??? | | |

| E|? |??? | e| |??? | | |

| F|? |??? | f| |??? | | |

| G|? |??? | g| |??? | | |

| H|? |??? | h| |??? | | |

| I|? |??? | i| |??? | | |

| J|? |??? | j| |??? | | |

| K| |??? | k| |??? | +| |

| L| |??? | l| |??? | /| |

| M| |??? | m| |??? |? |?? |

| N| |??? | n| |??? |? |?? |

| O| |??? | o| |??? |? |?? |

| P| |??? | p| |??? |? |?? |

| Q| |??? | q| |??? |? |?? |

| R| |??? | r| |??? |? |?? |

| S| |??? | s| |??? |? |?? |

| T| |??? | t| |??? |? |?? |

| U| |??? | u| |??? |? |?? |

| V| |??? | v| |??? |? |?? |

| W| |??? | w| |??? |? |?? |

| X| |??? | x| |??? |? |?? |

| Y| |??? | y| |??? |? |?? |

| Z| |??? | z| |??? |? |?? |

可以看到rowid是一个 进制的表示方式 利用上述对应表即可计算出

对象编号 AAAVcb? =

文件号 AAP =

块号 AAAAAL =

行号 AAA~AAJ = ~

进制的转换完全可以交给机器去做 Oracle也是这么认为的 于是提供了一个叫做dbms_rowid的包 它包含了一系列的方法 我们借助这个包就可完成上述的工作了

select rowid

?? substr(rowid ) || : || dbms_rowid rowid_object(rowid)?????? 数据对象编号/object_id

?? substr(rowid ) || : || dbms_rowid rowid_relative_fno(rowid) 文件编号/file_id

?? substr(rowid )|| : || dbms_rowid rowid_block_number(rowid) 块编号/block_id

?? substr(rowid )|| : || dbms_rowid ROWID_ROW_NUMBER(rowid)?? 行编号/row_num

from test_table

where rownum= ;

ROWID????????????? 数据对象编号/object_id??? 文件编号/file_id???? 块编号/block_id????? 行编号/row_num

AAAVcbAAPAAAAALAAA AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAA :

AAAVcbAAPAAAAALAAB AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAB :

AAAVcbAAPAAAAALAAC AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAC :

AAAVcbAAPAAAAALAAD AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAD :

AAAVcbAAPAAAAALAAE AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAE :

AAAVcbAAPAAAAALAAF AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAF :

AAAVcbAAPAAAAALAAG AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAG :

AAAVcbAAPAAAAALAAH AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAH :

AAAVcbAAPAAAAALAAI AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAI :

AAAVcbAAPAAAAALAAJ AAAVcb : ??????????? AAP : ???????????? AAAAAL : ????????? AAJ :

这个结果对不对呢?我们可以这样验证 注意 以下查询需要DBA权限

首先是object_id

select

?? owner object_name object_id

from dba_objects

where object_name= TEST_TABLE ;

OWNER????? OBJECT_NAME?????????? OBJECT_ID

TEST?????? TEST_TABLE???????????????

然后是文件编号和块编号

select

?? owner segment_name segment_type extent_id

?? file_id block_id blocks bytes

from dba_extents

where segment_name= TEST_TABLE ;

OWNER? SEGMENT_NAME? SEGMENT_TYPE?? EXTENT_ID? FILE_ID? BLOCK_ID? BLOCKS? BYTES

TEST?? TEST_TABLE??? TABLE????????????????? ?????? ???????? ?????? ?

TEST?? TEST_TABLE??? TABLE????????????????? ?????? ??????? ?????? ?

编号为 的块落在了编号为 的exntent上 只能说是验证了一半 接下来我们将数据块dump出来看看 不过做之前先为这一行打上 标记 看以下过程

test$logdw@logdw SQL select rowid t * from test_table t where rownum= ;

ROWID????????????????????? ID DATA

AAAVcbAAPAAAAALAAA????????? ????????????????????????????? Q

AAAVcbAAPAAAAALAAB????????? ????????????????????????????? Q

AAAVcbAAPAAAAALAAC????????? ????????????????????????????? Q

AAAVcbAAPAAAAALAAD????????? ????????????????????????????? Q

AAAVcbAAPAAAAALAAE????????? ????????????????????????????? Q

rows selected

test$logdw@logdw SQL update test_table set data=lpad( killkill ) where id= ;

row updated

test$logdw@logdw SQL select rowid t * from test_table t where rownum= ;

ROWID????????????????????? ID DATA

AAAVcbAAPAAAAALAAA????????? ?????????????????????? killkill

AAAVcbAAPAAAAALAAB????????? ????????????????????????????? Q

AAAVcbAAPAAAAALAAC????????? ????????????????????????????? Q

AAAVcbAAPAAAAALAAD????????? ????????????????????????????? Q

AAAVcbAAPAAAAALAAE????????? ????????????????????????????? Q

rows selected

test$logdw@logdw SQL mit;

做好了 标记 可以dump数据块了

sys$logdw@logdw SQL select get_trace_name() from dual ;

GET_TRACE_NAME()

/u /app/oracle/diag/rdbms/logdw/logdw/trace/logdw_ora_ trc

sys$logdw@logdw SQL alter system dump datafile block ;

System altered

打开trc文件 摘录如下

Start dump data blocks tsn: file#: minblk maxblk

Dump of memory from x A F A to x A F A

A F F C B ? [???????????? kil]

A F F C B C C C E C ? [lkill ??? ]

block_row_dump:

tab row @ x ac

tl: fb: H FL lb: x ? cc:

col? : [ ]? c

col? : [ ]

? b c

? c b c c

lishixinzhi/Article/program/Oracle/201311/17417

(责任编辑:IT教学网)

更多

推荐鼠标代码文章