推广 热搜: 缓解疲劳脚垫,  环保防静电桌垫,  63*125气缸  2022  收购ACF  回收ACF  济宁推杆  挡煤帘子  麻将  AH0.6/12矿用按钮箱 

rowid 、rowid去重

   日期:2023-04-07     浏览:33    评论:0    
核心提示:SQLite主键与RowID的是什么关系?默认情况下,SQLite会自动存在一个RowID列,从1开始,每添加一条记录+1当设置了主键,而且主键的类型为integer时,查询RowID等于主键主键设置

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去重的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

 
标签: 编号 主键 行号
打赏
 
更多>同类资讯
0相关评论

推荐资讯
网站首页  |  VIP套餐介绍  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  SITEMAPS  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报