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();
}
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
oracle中rowid怎么用,具体功能,***能讲的简单一些,谢谢了!
rowid 是查找一个表中记录的最快方式,比任何索引都要快。
下面***列就是rowid,至于为什么他是确定一条记录的最快方式,你可以查查他是由哪几部分组成的。
[SCOTT@orcl] SQLselect rowid,t.empno,t.ename from emp t;
ROWID EMPNO ENAME
------------------ ---------- ----------
AAAMgzAAEAAAAAgAAA 7369 SMITH
AAAMgzAAEAAAAAgAAB 7499 ALLEN
AAAMgzAAEAAAAAgAAC 7521 WARD
AAAMgzAAEAAAAAgAAD 7566 JONES
AAAMgzAAEAAAAAgAAE 7654 MARTIN
AAAMgzAAEAAAAAgAAF 7698 BLAKE
AAAMgzAAEAAAAAgAAG 7782 CLARK
AAAMgzAAEAAAAAgAAH 7788 SCOTT
AAAMgzAAEAAAAAgAAI 7839 KING
AAAMgzAAEAAAAAgAAJ 7844 TURNER
AAAMgzAAEAAAAAgAAK 7876 ADAMS
AAAMgzAAEAAAAAgAAL 7900 JAMES
AAAMgzAAEAAAAAgAAM 7902 FORD
AAAMgzAAEAAAAAgAAN 7934 MILLER
--你可以查询
[SCOTT@orcl] SQLselect empno,ename,job from emp where rowid = 'AAAMgzAAEAAAAAgAAN';
EMPNO ENAME JOB
---------- ---------- ---------
7934 MILLER CLERK
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
我们可能对oracle的rowid的使用并不陌生 不过 如果仔细分析一下 发现其还是有些知识点 rowid是一个伪列 是用来确保表中行的唯一性 它并不能指示出行的物理位置 但可以用来定位行 rowid是存储在索引中的一组既定的值(当行确定后) 我们可以像表中普通的列一样将它选出来 利用rowid是访问表中一行的最快方式 rowid需要 个字节来存储 显示为 位的字符串 rowid的组成结构为 data object number( 位字符串)+relative file number( 位字符串)+block number( 位字符串)+row number( 位字符串) 如 AAAADeAABAAAAZSAAA 我们可以借助oracle提供的包dbms_rowid 来对rowid进行解析从而获取关于行的相关信息 bossdb SQLselect rowid dbms_rowid rowid_object(rowid) obj_id dbms_rowid rowid_relative_fno(rowid) df# dbms_rowid rowid_block_number(rowid) blknum dbms_rowid rowid_row_number(rowid) rowno from p_test where rownum ;ROWID OBJ_ID DF# BLKNUM ROWNO AAAQ+tAANAAAC SAAA AAAQ+tAANAAAC SAAB AAAQ+tAANAAAC SAAC AAAQ+tAANAAAC SAAD 我们可以看到 通过rowid_row_number得到的行号是从 开始的 这是和rownum伪列的一个不同之处 我猜测rowid_row_number在求行号的时候是计算首行的偏移量 一般来说 当表中的行确定后 rowid就不会发生变化 但当如下情况发生时 rowid将发生改变 对一个表做表空间的移动后 对一个表进行了EXP/IMP后 lishixinzhi/Article/program/Oracle/201311/17378
关于rowid和rowid去重的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。