拓扑园

  • O&M
    • Universal部署
    • PHP+VUE+Laravel相关
  • Oracle性能优化
  • Oracle项目案例
    • Oracle近期项目案例(目录)
    • Oracle实战问题解析(目录)
    • Oracle数据库名变更流程(2种方式)
    • Oracle数据库目录更换流程(使用Oracle的clone工具)
    • Oracle数据库迁移方案(目录)
    • 标准化文档系列
  • Oracle基础知识
    • LLL的Oracle培训(分类)
    • LLL的docker培训(分类)
    • 标准化文档系列--(分类)
    • Oracle核心经典分析(分类)
    • 图灵小队----(分类并包含以下文章)
    • --MySQL8.0/Oracle/Memcached/Redis等安装配置于RHEL/OL6/7/8.X系列-运行环境最优配置
    • --PG安装配置于RHEL/9X系列-运行环境最优配置
    • --自动维护任务详解-开启、关闭信息统计收集(统计信息)
    • --图灵小队—Oracle/PostgreSQL下创建一个用户测试表(自行定义数据行)
    • --图灵小队-Oracle存储过程导出表的明细_UTL_FILE(文章)
    • --图灵小队-Oracle数据库删除/卸载操作指南(文章)
    • --图灵小队-Oracle常用性能查询SQL语句(文章)
    • --图灵小队-Oracle数据库上线前检查(文章)
    • --图灵小队-Oracle常用SQL语句(文章)
    • --图灵小队—Linux/Oracle脚本/MySQL合集(持续更新)
    • --图灵小队-Oracle技巧记录(文章)
    • ADG
    • RAC
    • ASM
    • OGG
    • RMAN
    • EXPDP/IMPDP
    • 工厂数据导入导出系列
  • MySQL
    • MySQL数据库规范
    • MySQL项目案例
    • MySQL安装配置
    • MYSQL集群项目
    • MySQL常见处理
    • MySQL-Sysbench专题
    • MySQL-Percona Toolkit专题
  • Linux
    • Shell编程
    • kubernetes
    • docker
    • Linux
    • PHP
    • Nginx
    • haproxy
    • mail
    • 网站
    • 域名
    • 网址收藏
  • 数据中心
    • 新框架系统集合
    • 工作文档
    • EBS数据文件扩容
    • VMware虚拟化
    • EBS系列
    • 大数据
    • SVN
    • zabbix
    • SAP
    • 备份相关
    • FC交换机
    • SVN
  • K-Studing
    • D8-Python学习
    • Oracle/MySQl等面试题
    • LG-MySQL
    • LG-Docker/K8S
    • LG-PostgreSQL
    • LG-ORACLE_BBED
    • LG-ORACLE
    • LG-Elasticsearch(ES)+ELK
    • Oracle-19C-OCP
    • WERN_ORACLE培训
    • redis数据库
    • Nginx培训学习系列
  • 其他
    • 外研英语4年级下册-听力
    • 影视系列
    • 如何使用iTunes软件通过抓包下载旧版本的ios的app
天高任鸟飞
Oracle/MySQL数据库恢复/数据迁移/生产规范报告技术交流:TEL:18562510581(微信同号);加微信入群
  1. 首页
  2. Oracle基础知识
  3. 图灵小队
  4. 正文

Oracle中ROWID的内部解析

2023年9月22日 1591点热度 0人点赞 0条评论

目录

  • 一、关于ROWID的解释
    • 1、概念
    • 2、ROWID和索引的关系
    • 3、索引中的rowid
  • 二、ROWID的格式:
    • 1、rowid的格式
    • 2、举个例子
      • (1)创建表
      • (2)直接查看空表的rowid和对象ID
      • (3)插入数据
      • (4)重新查看表test
    • (5)查看此表所在的文件及块位置
    • 3、ROWD的表示方法
    • 4、获得ROWD与手动计算
      • (1)获取ROWID
      • (2)第一部分6位表示:
      • (3)第二部分3位表示:
      • (4)第三部分6位表示:
      • (5)第四部分3位表示:
    • 5、查询sql(获取文件对象,文件号及块位置)

一、关于ROWID的解释

1、概念

ROWID是ORACLE中的一个重要的概念。用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即被确定且唯一。

ROWID它是一个伪列,它并不实际存在于表中。它是ORACLE在读取表中数据行时,根据每一行数据的物理地址信息编码而成的一个伪列。

所以根据一行数据的ROWID能找到一行数据的物理地址信息。从而快速地定位到数据行。

数据库的大多数操作都是通过ROWID来完成的,而且使用ROWID来进行单记录定位速度是最快的。

2、ROWID和索引的关系

要理解索引,必须先搞清楚ROWID。

B-Tree索引的每个索引条目具有两个字段。

第一个字段表示索引的键值,对于单列索引来说是一个值;而对于多列索引来说则是多个值组合在一起的。

第二个字段表示键值所对应的记录行的ROWID。所以索引能加快查询速度!

索引值→ROWID->将ROWID换算成一行数据的物理地址->得到一行数据

3、索引中的rowid

二、ROWID的格式:

1、rowid的格式

第一部分6位表示:该行数据所在的数据对象的 data_object_id;
第二部分3位表示:该行数据所在的相对数据文件的id;
第三部分6位表示:该数据行所在的数据块的编号;
第四部分3位表示:该行数据的行的编号;

索引就是保存了rowid后三个部分的信息。

索引是物理存在的,而rowid是伪列。所以索引可以用来快速地定位到数据行。

2、举个例子

(1)创建表

create table test(id number,name varchar2(10));

(2)直接查看空表的rowid和对象ID

col name for a10;
select rowid,dump(rowid,16)as dump ,a.* from test a where rownum<10;
col object_name for a15;
col object_type for a15;
select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID,OBJECT_TYPE from dba_objects where owner='TEST' and object_name='TEST';

(3)插入数据

insert into test values(1,'LLL01');
insert into test values(2,'LLL02');
insert into test values(3,'LLL04');
insert into test values(4,'LLL04');
insert into test values(5,'LLL05');
commit;

(4)重新查看表test

col name for a10; 
select rowid,dump(rowid,16)as dump ,a.* from test a where rownum<10;

(5)查看此表所在的文件及块位置

col segment_name for a10;
col segment_type for a15;
select owner,segment_name,segment_type,FILE_ID,BLOCK_ID from dba_extents where segment_name='TEST';

select owner,segment_name,segment_type,header_block from dba_segments where owner='TEST'and segment_name='TEST';

3、ROWD的表示方法

Oracle的物理扩展ROWID有18位,每位采用64位编码,分别用A~Z、a~z、0~9、+、/共64个字符表示。

A~Z表示0到25;a~z表示26到51;0~9表示52到61;+表示62;/表示63;刚好64个字符。

4、获得ROWD与手动计算

(1)获取ROWID

select rowid,dump(rowid,16)as dump ,a.* from test a where rownum<10;
ROWID                      DUMP                                   ID       NAME
------------------   ---------------------------------------- ---------- ----------
AAAlasAAEAAAACbAAA    Typ=69 Len=10: 0,2,56,ac,1,0,0,9b,0,0       1        LLL01
AAAlasAAEAAAACbAAB    Typ=69 Len=10: 0,2,56,ac,1,0,0,9b,0,1       2        LLL02
AAAlasAAEAAAACbAAC    Typ=69 Len=10: 0,2,56,ac,1,0,0,9b,0,2       3        LLL03
AAAlasAAEAAAACbAAD    Typ=69 Len=10: 0,2,56,ac,1,0,0,9b,0,3       4        LLL04
AAAlasAAEAAAACbAAE    Typ=69 Len=10: 0,2,56,ac,1,0,0,9b,0,4       5        LLL05

(2)第一部分6位表示:

该行数据所在的数据对象的 data_object_id;

AAAlas(根据64位编码表获取)
-->0,0,0,37,26,44
-->select 0*64*64*64*64*64+0*64*64*64*64+0*64*64*64+37*64*64+26*64+44*1 from dual;
-->153260
-->select to_char(153260,'XXXXXXX') as hex_value from dual;
-->256AC

(3)第二部分3位表示:

该行数据所在的相对数据文件的id;

AAE(根据64位编码表获取)
-->0,0,4
-->select 0*64*64+0*64+4*1 from dual;
-->4
-->select to_char(4,'X') as hex_value from dual;
-->4

(4)第三部分6位表示:

该数据行所在的数据块的编号;

AAAACb
-->0,0,0,0,2,27
-->select 0+0+0+0+2*64+27*1 from dual;
-->155
-->select to_char(155,'XXX') as hex_value from dual;
-->9B

(5)第四部分3位表示:

该行数据的行的编号;

AAA
-->0,0,0
-->select 0+0+0 from dual;
-->0

最终定位到对象object的id是153260,文件号是4,块是155,行位置是第0位,也就是第一行。

5、查询sql(获取文件对象,文件号及块位置)

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 test where rownum<10;

显然这个结果和我们手动计算的结果是一致的。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2023年9月22日

admin

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

COPYRIGHT © 2022 拓扑园. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

鲁ICP备2021020523号

鲁ICP备2021020523号