PostgreSQL ctid与Oracle rowid的区别
发布时间:2022-08-25 20:10:14 所属栏目:点评 来源:
导读: Oracle:搞过Oracle的一定对rowid比较熟悉啦,由下面基本含义组成SELECT ROWID, DBMS_ROWID.ROWID_OBJECT(ROWID) A
Oracle: 搞过Oracle的一定对rowid比较熟悉啦,由下面基本含义组成 SELECT ROWID, DBMS_ROWID.ROWID_OBJECT(ROWID) AS OBJECT, DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) AS FILENUM, DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) AS BLOCK, DBMS_ROWID.ROWID_ROW_NUMBER(ROWID) AS ROWN FROM emp; ROWID OBJECT FILENUM BLOCK ROWN------------------ ---------- ---------- ---------- ----------AAAUIRAABAAAg8pAAA 82449 1 134953 0AAAUIRAABAAAg8pAAB 82449 1 134953 1AAAUIRAABAAAg8pAAC 82449 1 134953 2AAAUIRAABAAAg8pAAD 82449 1 134953 3AAAUIRAABAAAg8pAAE 82449 1 134953 4AAAUIRAABAAAg8pAAF 82449 1 134953 5AAAUIRAABAAAg8pAAG 82449 1 134953 6AAAUIRAABAAAg8pAAH 82449 1 134953 7AAAUIRAABAAAg8pAAI 82449 1 134953 8AAAUIRAABAAAg8pAAJ 82449 1 134953 9AAAUIRAABAAAg8pAAK 82449 1 134953 10AAAUIRAABAAAg8pAAL 82449 1 134953 11AAAUIRAABAAAg8pAAM 82449 1 134953 12AAAUIRAABAAAg8pAAN 82449 1 134953 13SQL>select OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID from dba_objects where OBJECT_NAME='EMP';OBJECT_NAME OBJECT_ID DATA_OBJECT_ID-------------------- ---------- --------------EMP 82449 82449SQL>alter table emp move; SQL>select OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID from dba_objects where OBJECT_NAME='EMP';OBJECT_NAME OBJECT_ID DATA_OBJECT_ID-------------------- ---------- --------------EMP 82449 84675 ROWID OBJECT FILENUM BLOCK ROWN------------------ ---------- ---------- ---------- ----------AAAUrDAABAAAhSpAAA 84675 1 136361 0AAAUrDAABAAAhSpAAB 84675 1 136361 1AAAUrDAABAAAhSpAAC 84675 1 136361 2AAAUrDAABAAAhSpAAD 84675 1 136361 3AAAUrDAABAAAhSpAAE 84675 1 136361 4AAAUrDAABAAAhSpAAF 84675 1 136361 5AAAUrDAABAAAhSpAAG 84675 1 136361 6AAAUrDAABAAAhSpAAH 84675 1 136361 7AAAUrDAABAAAhSpAAI 84675 1 136361 8AAAUrDAABAAAhSpAAJ 84675 1 136361 9AAAUrDAABAAAhSpAAK 84675 1 136361 10AAAUrDAABAAAhSpAAL 84675 1 136361 11AAAUrDAABAAAhSpAAM 84675 1 136361 12AAAUrDAABAAAhSpAAN 84675 1 136361 1314 rows selected. 可以看到data object number和块号变了,如果move到另外的tablespace那么 file number也会变 PostgreSQL: lightdb@postgres=# select relname,oid,relfilenode from pg_class where relname = 'emp'; relname | oid | relfilenode ---------+-------+------------- emp | 31396 | 31396(1 row)lightdb@postgres=# truncate table emp;TRUNCATE TABLElightdb@postgres=# select relname,oid,relfilenode from pg_class where relname = 'emp'; relname | oid | relfilenode ---------+-------+------------- emp | 31396 | 31407(1 row) 可以看到PostgreSQL的行为和Oracle很类似呀,oid对应Oracle的object_id,relfilenode对应Oracle的data_object_id,前者是逻辑对象,后者是实体对象 那么看下PostgreSQL的ctid vacuum full之后,数据行在块内的物理位置就会移动,即ctid会发生变化,所以ctid不能作为长期的行标识符,应该使用主键来标识一个逻辑行。 ctid由两个数字组成,第一个数字表示物理块号,第二个数字表示在物理块中的行号,所以说PostgreSQL的ctid是表级别唯一的行,而Oracle中是整个实例中唯一。 lightdb@postgres=# select ctid,empno from emp; ctid | empno --------+------- (0,1) | 7369 (0,2) | 7499 (0,3) | 7521 (0,4) | 7566 Oracle可以用rowid 删除表中重复的数据,那么PostgreSQL同样也是可以的 lightdb@postgres=# select * from t_test; id ---- 1 2 2 3(4 rows)delete from t_test where ctid in (select ctid from(SELECT ctid, id, count(*) OVER (PARTITION BY id ORDER BY ctid) as cnt FROM t_test ) where cnt > 1) returning *; (编辑:泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐