字段数据oracle rowid and postgresql ctid

本文是一篇关于字段数据的帖子

    首先分析一下oracle rowid,数据库表行中的物理标识

    

    

SQL> select rowid from book_info where rownum<=1;

ROWID
------------------
AAAQTJAAaAAAAoaAAA

    


    每日一道理
听,是谁的琴声,如此凄凉,低调的音,缓慢的节奏,仿佛正诉说着什么。音低调得略微有些抖动,听起来似乎心也有些抖动,我感觉到一种压抑的沉闷气息,是否已凝结在这空气中……

    

ROWID的格式如下:

数据对象编号        文件编号        块编号           行编号
OOOOOO             FFF             BBBBBB          RRR

由此看出,AAAQTJ是数据对象编号,AAa是文件编号,AAAAoa是块编号,AAA是行编号

 

select rowid ,

substr(rowid,1,6) "OBJECT",

substr(rowid,7,3) "FILE",

substr(rowid,10,6) "BLOCK",

substr(rowid,16,3) "ROW"

from book_info where rownum<=5;

查出64位码编的值:

 

ROWID              OBJECT     FILE       BLOCK      ROW

------------------ ---------- ---------- ---------- ------------------------------------------------------

AAAQTJAAaAAAAoCAAB AAAQTJ     AAa        AAAAoC     AAB

AAAQTJAAaAAAAoCAAC AAAQTJ     AAa        AAAAoC     AAC

AAAQTJAAaAAAAoCAAD AAAQTJ     AAa        AAAAoC     AAD

AAAQTJAAaAAAAoCAAE AAAQTJ     AAa        AAAAoC     AAE

AAAQTJAAaAAAAoCAAF AAAQTJ     AAa        AAAAoC     AAF

查出10进制的值:

 

SQL> select dbms_rowid.rowid_object(rowid)  object_id, dbms_rowid.rowid_relative_fno(rowid) file_id,

        dbms_rowid.rowid_block_number(rowid)  block_id ,dbms_rowid.rowid_row_number(rowid)  num from book_info where             rownum<=5;


 OBJECT_ID    FILE_ID   BLOCK_ID        NUM

---------- ---------- ---------- ----------

     66761         26       2568          0

     66761         26       2568          1

     66761         26       2568          2

     66761         26       2568          3

     66761         26       2568          4

取获rowid函数:

 

create or replace function get_rowid

(l_rowid in varchar2)

return varchar2

is

ls_my_rowid     varchar2(200);          

rowid_type     number;          

object_number     number;          

relative_fno     number;          

block_number     number;          

row_number     number; 

begin

 dbms_rowid.rowid_info(l_rowid,rowid_type,object_number,relative_fno, block_number, row_number);          

 ls_my_rowid := 'Object# is      :'||to_char(object_number)||chr(10)||

        'Relative_fno is :'||to_char(relative_fno)||chr(10)||

        'Block number is :'||to_char(block_number)||chr(10)||

        'Row number is   :'||to_char(row_number);

 return ls_my_rowid ;

end;         

/


select get_rowid(rowid) from book_info where rownum<=1;

 

Object# is      :66761

Relative_fno is :26

Block number is :2586

Row number is   :0

当然最经常用使的是用rowid去除复重:

查出复重数据:

 

select a.rowid,a.* from 表名 a 

where a.rowid != 

(

   select max(b.rowid) from 表名 b 

   where a.字段1 = b.字段1 and 

   a.字段2 = b.字段2 

)

除删复重数据:

 

delete from 表名 a 

where a.rowid != 

(

   select max(b.rowid) from 表名 b 

   where a.字段1 = b.字段1 and 

   a.字段2 = b.字段2 

)

对于整行都复重的那么,可以用使distinct函数。


以下分析下postgresql的ctid

 

testuser=# select ctid,* from t1 limit 1;

 ctid  |     a     

-------+-----------

 (0,1) | 100000000

和oracle rowid相似也是一个物理字段,动自成生,不过结构和oracle rowid不一样,可以看到是(blockid,itemid)

ctid在数据变动后也会化变。


利用ctid去除复重数据:

建立测试表,插入数据:

 

testuser=# create table t2 (id int,name varchar(20));

CREATE TABLE

testuser=# insert into t2 values (1,'apple');

INSERT 0 1

testuser=# insert into t2 values (1,'apple');

INSERT 0 1

testuser=# insert into t2 values (1,'apple');

INSERT 0 1

testuser=# insert into t2 values (2,'orange');

INSERT 0 1

testuser=# insert into t2 values (2,'orange');

INSERT 0 1

testuser=# insert into t2 values (2,'orange');

INSERT 0 1

testuser=# insert into t2 values (2,'orange');

INSERT 0 1

testuser=# insert into t2 values (3,'banana');

INSERT 0 1

testuser=# insert into t2 values (3,'banana');

INSERT 0 1


 

testuser=# select * from t2;

 id |  name  

----+--------

  1 | apple

  1 | apple

  1 | apple

  2 | orange

  2 | orange

  2 | orange

  2 | orange

  3 | banana

  3 | banana

查询复重的数据:

 

testuser=# select ctid,* from t2 where ctid in (select min(ctid) from t2 group by id);

 ctid  | id |  name  

-------+----+--------

 (0,1) |  1 | apple

 (0,4) |  2 | orange

 (0,8) |  3 | banana

除删复重数据并看查结果:

 

testuser=# delete from t2 where  ctid not in (select min(ctid) from t2 group by id);

DELETE 6

testuser=# select * from t2;

 id |  name  

----+--------

  1 | apple

  2 | orange

  3 | banana

(3 rows)

文章结束给大家分享下程序员的一些笑话语录:  一边用着越狱的ip,一边拜乔帮主的果粉自以为是果粉,其实在乔帮主的眼里是不折不扣的叛徒。

posted @ 2013-05-08 19:53  坚固66  阅读(704)  评论(0编辑  收藏  举报