zoukankan      html  css  js  c++  java
  • rowid 相关

    Oracle中ROWID详解

    来源:https://blog.csdn.net/qq_36249352/article/details/79494162

    沃德天•维森莫•拉莫帅 2019-07-04 19:31:07 3357 收藏 4
    分类专栏: 数据库 文章标签: Oracle中的rowid
    版权
    ROWID是ORACLE中的一个重要的概念。用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即被确定且唯一。ROWID它是一个伪列,它并不实际存在于表中。它是ORACLE在读取表中数据行时,根据每一行数据的物理地址信息编码而成的一个伪列。所以根据一行数据的ROWID能找到一行数据的物理地址信息。从而快速地定位到数据行。数据库的大多数操作都是通过ROWID来完成的,而且使用ROWID来进行单记录定位速度是最快的。

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

    B-Tree索引的每个索引条目具有两个字段。第一个字段表示索引的键值,对于单列索引来说是一个值;而对于多列索引来说则是多个值组合在一起的。第二个字段表示键值所对应的记录行的ROWID。所以索引能加快查询速度!

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

    一、ROWID的格式:


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

    索引就是保存了rowid后三个部分的信息。索引是物理存在的,而rowid是伪列。所以索引可以用来快速地定位到数据行。

    data_object_id

    下面以SAKILA数据库的ACTOR表为例

    这里我们要注意将 data_object_id  与 object_id 区分开来,前者是oracle为它的每一个对象唯一分配的id,而后者与表ACTOR对应的“段”有关,是存放表tt的段的id,也就是与存放表tt中数据的物理位置有关:

    select owner,object_id,data_object_id,status from dba_objects where object_name='ACTOR';


    alter table ACTOR move tablespace users;

    select owner,object_id,data_object_id,status from dba_objects where object_name='ACTOR';


    我们看到当表ACTOR move到了users表空间时,段发生了改变,物理位置发生了变化,从而 DATA_OBJECT_ID 也发生了变化。我们知道表是存放在“表段”中的,索引是存放在“索引段”中的。DATA_OBJECT_ID就是表示存放数据的“数据段对象的id”

    相对文件编码

    关于相对文件编码和绝对文件编号:相对文件id是指相对于表空间,在表空间唯一,绝对文件是指相当于全局数据库而言的,全局唯一;

    select file_name,file_id,relative_fno from dba_data_files;


    rowid采用64进制来编码

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

    Base64编码表
    码值 字符   码值 字符   码值 字符   码值 字符
    0 A 16 Q 32 g 48 w
    1 B 17 R 33 h 49 x
    2 C 18 S 34 i 50 y
    3 D 19 T 35 j 51 z
    4 E 20 U 36 k 52 0
    5 F 21 V 37 l 53 1
    6 G 22 W 38 m 54 2
    7 H 23 X 39 n 55 3
    8 I 24 Y 40 o 56 4
    9 J 25 Z 41 p 57 5
    10 K 26 a 42 q 58 6
    11 L 27 b 43 r 59 7
    12 M 28 c 44 s 60 8
    13 N 29 d 45 t 61 9
    14 O 30 e 46 u 62 +
    15 P 31 f 47 v 63 /
    二、使用rowid访问数据的执行计划
    SELECT t.*, ''||t.ROWID FROM "SAKILA"."ACTOR" t;


    EXPLAIN PLAN FOR
    select * FROM ACTOR where rowid='AAAYEVAAJAAAACrAAA';
    select * from table(DBMS_XPLAN.DISPLAY)


    三、例子:如何从rowid计算得到obj#,rfile#,block#,row#
    我们演示一下具体的计算方法:

    SELECT t.*, ''||t.ROWID FROM "SAKILA"."ACTOR" t;


    表sakila的 data_object_id 为 AAAYEVAAJAAAACrAAA的前6位:AAAYEV,那么我们来计算一下 AAAYEV的值到底是多少:

    查询Base64编码表

    码值 字符
    0 A
    24 Y
    4 E
    21 V
    select 24 * 64 * 64 + 4 * 64 + 21 from dual;

    AAAYEV=24 * 64 * 64 + 4 * 64 + 21=98581

    然后我们查询字典表,看两种方法得到的值是否相等:

    select owner,object_id,data_object_id,status from dba_objects where object_name='ACTOR';


    我们看到通过rowid计算得到的data_object_id和通过字典表查到的值相等!

    表ACTOR的相对文件编号为 AAAYEVAAJAAAACrAAA 的中的 AAJ,显然查表可知 AAJ= 9;

    我们在再来查询字典表:

    可以看到字典表显示relative_fno为9的数据文件为C:APPORACLEORADATAORCLPDBORCLSAMPLE_SCHEMA_USERS01.DBF

    查询当前数据库中的users表空间和对应的数据文件

    select file_name,tablespace_name from dba_data_files;


    两者结果一致。

    而我们前面执行过:alter table ACTOR move tablespace users;所以两种方式得到的结果是一致的。

    表ACTOR中的第一行数据存放的block的编号为 AAAYEVAAJAAAACrAAA 中的 AAAACr,而AAAACr =2*64+43=171 
    表ACTOR中的第一行数据存放的行的编号为AAAYEVAAJAAAACrAAA 中的 AAA,显然值为0,即第一行。

    我们也可以通过Oracle提供的存储过程来计算出上面的值:

    SELECT

    dbms_rowid.rowid_object (ROWID) data_object_id,

    dbms_rowid.rowid_relative_fno (ROWID) relative_fno,

    dbms_rowid.rowid_block_number (ROWID) block_no,

    dbms_rowid.rowid_row_number (ROWID) row_no

    FROM

    ACTOR;
     

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

    原文链接:https://blog.csdn.net/u012279452/article/details/94646376

    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) Row_Number
    From Emp;

    Select Owner,
    Object_Id,
    Data_Object_Id,
    Status
    From Dba_Objects
    Where Object_Name = 'EMP';


    alter table EMP move tablespace cuxd;

    select file_name,file_id,relative_fno from dba_data_files;

  • 相关阅读:
    2017寒假作业二 汇总随笔
    2017寒假作业一
    UVA 1601 POJ 3523 The Morning after Halloween 【双向BFS】【A*】 (好题)
    UVA 10570 Meeting with Aliens 【枚举+结论题】
    UVA 1614 Hell on the Markets 【贪心+结论题】
    UVA 10603 Fill【BFS】
    Codevs 1288 埃及分数 【IDA*】
    UVA 11212 Editing a Book 【IDA*】
    UVA 11624 Fire! 【特殊BFS】
    UVA 1599 Ideal Path 【两次BFS+贪心】 (好题)
  • 原文地址:https://www.cnblogs.com/shuihaya/p/14592650.html
Copyright © 2011-2022 走看看