ROWID简述
Oracle中的ROWID用于唯一标识数据库表中的一行记录,它反映了该行数据的物理存储位置。在大多数情况下,ROWID是稳定的,但在特定操作下会发生变化。
在以下情况rowid可能会发生变化:
1行被物理移动时:如果对表进行重组(如ALTER TABLE … MOVE)、收缩表空间、分区操作或数据迁移,行的物理位置改变,ROWID会更新。
2.行迁移(Row Migration):当某行数据更新后无法容纳在原数据块中,Oracle会将其迁移到新块,并在原位置保留指向新位置的指针。此时,通过查询得到的ROWID会指向新地址。
3.分区表操作:对分区表进行SPLIT、MERGE或MOVE分区等操作时,相关行的ROWID可能改变。
4.闪回操作(Flashback):使用FLASHBACK TABLE恢复表到先前状态时,可能导致ROWID变化。
5.导入/导出(Export/Import):使用EXP/IMP或数据泵(Data Pump)工具导出再导入数据时,ROWID会重新生成
常规的DML不会让rowid发生改变,除非因为行迁移导致的物理位置发生改变
磐维A兼容模式下的ROWID
磐维中有ctid系统列,表示行的物理位置标识符,类似于Oracle的rowid,通过ctid适配兼容oracle的rowid,目前只部分兼容,两者存在部分差异
兼容测试
磐维系统表是不能查询rowid的,只有在A模式下新建的表存在伪列rowid
test=# select datcompatibility from pg_database;
datcompatibility
------------------
A
A
A
A
A
(5 行记录)
test=# select rowid from pg_databsae limit 1;
错误: 关系 "pg_databsae" 不存在在 dn_6001
第1行select rowid from pg_databsae limit 1;
test=# create table test(c1 varchar(10),c2 varchar(10));
CREATE TABLE
test=# insert into test values ('aaa','aaa');
INSERT 0 1
test=# select * from test;
c1 | c2
-----+-----
aaa | aaa
(1 行记录)
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AQA= | aaa | aaa
(1 行记录)
磐维中进行增删改操作
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AQA= | aaa | aaa
test=# update test set c2 = 'bbb' where c2 = 'aaa';
UPDATE 1
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AgA= | aaa | bbb
(1 行记录)
test=# insert into test values ('ccc','ccc');
INSERT 0 1
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AgA= | aaa | bbb
v40AAA==AAAAAA==AwA= | ccc | ccc
(2 行记录)
test=# insert into test values ('ddd','ddd');
INSERT 0 1
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AgA= | aaa | bbb
v40AAA==AAAAAA==AwA= | ccc | ccc
v40AAA==AAAAAA==BAA= | ddd | ddd
(3 行记录)
test=# delete from test where c2='ccc';
DELETE 1
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AgA= | aaa | bbb
v40AAA==AAAAAA==BAA= | ddd | ddd
(2 行记录)
test=# insert into test values ('eee','eee');
INSERT 0 1
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AgA= | aaa | bbb
v40AAA==AAAAAA==BAA= | ddd | ddd
v40AAA==AAAAAA==BQA= | eee | eee
在oracle中,正常修改数据是不会改变rowid
且oracle单表非聚合视图中也带有rowid,磐维没有适配,如需在视图中查询rowid,需创建视图时将rowid伪列带上
test=# create view v1 as select * from test;
CREATE VIEW
test=# select rowid,* from v1;
错误: 字段 "rowid" 不存在
第1行select rowid,* from v1;
^
背景: 引用列 rowid
test=# create view v2 as select rowid,* from test;
CREATE VIEW
test=# select * from v2;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==AgA= | aaa | bbb
v40AAA==AAAAAA==BAA= | ddd | ddd
v40AAA==AAAAAA==BQA= | eee | eee
(3 行记录)
test=# update test set c2 = 'aaa' where c2 = 'bbb';
UPDATE 1
test=# select rowid,* from test;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==BAA= | ddd | ddd
v40AAA==AAAAAA==BQA= | eee | eee
v40AAA==AAAAAA==BgA= | aaa | aaa
(3 行记录)
test=# select * from v2;
rowid | c1 | c2
----------------------+-----+-----
v40AAA==AAAAAA==BAA= | ddd | ddd
v40AAA==AAAAAA==BQA= | eee | eee
v40AAA==AAAAAA==BgA= | aaa | aaa
(3 行记录)
结论
磐维增加和删除数据不会修改rowid,而更新数据和oracle有区别,会修改rowid,非聚合视图也暂时不支持默认创建虚拟列rowid




