来源:网友投稿 浏览数:4675 关注:380人
大家好,近很多小伙伴在关注rowid,以下是(www.liyan0123)小编整理的与rowid相关的内容分享给大家,一起来看看吧。
本文目录一览:
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唯一标识每条记录所在的位置 它作为一个伪列在查询中出现
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列,从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();
}
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
=========================================
特别声明:以上内容来源于网友投稿,编辑整理发布,如有不妥之处,请与我方联系删除处理。