首页 百科 正文
rowid(Oracle数据库中rowid什么作用?)

来源:网友投稿 浏览数:4675 关注:380人

大家好,近很多小伙伴在关注rowid,以下是(www.liyan0123)小编整理的与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

w ere

t.rn

between

2

and

10;

查找前三名的记录

select

*

from

emp

a

w ere

rownum

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

例如:

select

*

from

(select

rownum

rn,

a.*

from

emp

a)

t

w ere

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

w ere

rowid

not

in

(select

max(rowid)

from

stu

b

w ere

a.name

=

b.name

and

a.stno

b.stno);

这样就可以了。

说说Oracle的rowid

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

select rowid id

from test_table

w ere rownum= ;

ROWID                      ID

AA**cbAAPAAAAALAAA         

AA**cbAAPAAAAALAAB         

AA**cbAAPAAAAALAAC         

AA**cbAAPAAAAALAAD         

AA**cbAAPAAAAALAAE         

AA**cbAAPAAAAALAAF         

AA**cbAAPAAAAALAAG         

AA**cbAAPAAAAALAAH         

AA**cbAAPAAAAALAAI         

AA**cbAAPAAAAALAAJ        

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

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

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

| A|  |    | a| |    | | |

| B|  |    | b| |    | | |

| C|  |    | c| |    | | |

| D|  |    | d| |    | | |

| E|  |    | e| |    | | |

| F|  |    | f| |    | | |

| G|  |    | g| |    | | |

| 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是一个 进制的表示方式 利用上述对应表即可计算出

对象编号 AA**cb  =

文件号 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

w ere rownum= ;

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

AA**cbAAPAAAAALAAA AA**cb :             AAP :              AAAAAL :           AAA :

AA**cbAAPAAAAALAAB AA**cb :             AAP :              AAAAAL :           AAB :

AA**cbAAPAAAAALAAC AA**cb :             AAP :              AAAAAL :           AAC :

AA**cbAAPAAAAALAAD AA**cb :             AAP :              AAAAAL :           AAD :

AA**cbAAPAAAAALAAE AA**cb :             AAP :              AAAAAL :           AAE :

AA**cbAAPAAAAALAAF AA**cb :             AAP :              AAAAAL :           AAF :

AA**cbAAPAAAAALAAG AA**cb :             AAP :              AAAAAL :           AAG :

AA**cbAAPAAAAALAAH AA**cb :             AAP :              AAAAAL :           AAH :

AA**cbAAPAAAAALAAI AA**cb :             AAP :              AAAAAL :           AAI :

AA**cbAAPAAAAALAAJ AA**cb :             AAP :              AAAAAL :           AAJ :

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

首先是object_id

select

   owner object_name object_id

from dba_objects

w ere 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

w ere 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 w ere rownum= ;

ROWID                      ID DATA

AA**cbAAPAAAAALAAA                                        Q

AA**cbAAPAAAAALAAB                                        Q

AA**cbAAPAAAAALAAC                                        Q

AA**cbAAPAAAAALAAD                                        Q

AA**cbAAPAAAAALAAE                                        Q

rows selected

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

row updated

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

ROWID                      ID DATA

AA**cbAAPAAAAALAAA                                 killkill

AA**cbAAPAAAAALAAB                                        Q

AA**cbAAPAAAAALAAC                                        Q

AA**cbAAPAAAAALAAD                                        Q

AA**cbAAPAAAAALAAE                                        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

lis ixinz i/Article/program/Oracle/201311/17417

SQLite主键与RowID的是什么关系?

默认情况下,SQLite会自动存在一个RowID列,从1开始,每添加一条记录+1

当设置了主键,而且主键的类型为integer时,查询RowID等于主键

主键设置为integer时,对rowid和主键的查询情况

create table aaa(id integer PRIMARY KEY,aaa ntext)

只有在设置为Integer时才会替代rowid,设置为int或其它都不行,下图为主键设置成int类型

create table aaa(id int PRIMARY KEY,aaa ntext)

写入效率对比:

插入500W记录,不设置主键,利用rowid,写入时间1分13秒

插入500W记录,设置Integer主键,写入时间1分19秒

检索效率对比:

对设置了integer主键的表,查询主键100W次,耗时1分20秒

对设置了integer主键的表,查询rowid 100W次,耗时1.22秒

对不设置主键的表,查询rowid 100W次,耗时1.23秒

(这2秒左右的差距,判断有两种可能,第一是程序运行时误差,第二种可能是因为主键是ID,比rowid长度小,所以拼接sql语句时,要占时间优势)

检索优化:

每次检索对command赋值,耗时约1分20秒

[cs arp]

SQLiteCommand cmd = new SQLiteCommand(conn);

for (int i = 0; i 1000000; i++)

{    

cmd.CommandText = "select * from aaa w ere id=" + (1000000 + i);

cmd.ExecuteNonQuery();

}

每次检索对参数赋值,耗时约58秒

[cs arp]

SQLiteCommand cmd = new SQLiteCommand(conn);

cmd.CommandText = "select * from aaa w ere id=@id";

cmd.Parameters.Add("id", DbType.Int32);

for (int i = 0; i 1000000; i++)

{    

cmd.Parameters[0].Value = (1000000 + i);

cmd.ExecuteNonQuery();

}

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 w ere id = 1;

4.查看rowid

select rowid,row_id from test_rowid;

以上就是rowid的相关介绍,希望能对大家有所帮助。

获赞:470 | 收藏:76 | 发布时间:2024-05-16 15:39:44

  •  标签:  

原文链接:http://www.liyan0123.com/42809.html

=========================================

特别声明:以上内容来源于网友投稿,编辑整理发布,如有不妥之处,请与我方联系删除处理。

推荐阅读