"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什么作用?
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
在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
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秒
[csharp]
SQLiteCommand cmd = new SQLiteCommand(conn);
for (int i = 0; i 1000000; i++)
{
cmd.CommandText = "select * from aaa where id=" + (1000000 + i);
cmd.ExecuteNonQuery();
}
每次检索对参数赋值,耗时约58秒
[csharp]
SQLiteCommand cmd = new SQLiteCommand(conn);
cmd.CommandText = "select * from aaa where 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用法、rowid的信息别忘了在本站进行查找喔。