简单分析oracle的数据存储

简介: 在数据库的存储结构中,我们知道一般来说一个表都存储在对应的数据文件里,数据文件可以分为多个段,一般来说一个表会对应一个数据段,单纯考虑数据段的时候,数据段又可以分为多个区,每个区都可以分为若干个数据块,在操作系统层面,有对应的数据块和数据库层面的数据块有一个映射...
在数据库的存储结构中,我们知道一般来说一个表都存储在对应的数据文件里,数据文件可以分为多个段,一般来说一个表会对应一个数据段,单纯考虑数据段的时候,数据段又可以分为多个区,每个区都可以分为若干个数据块,在操作系统层面,有对应的数据块和数据库层面的数据块有一个映射,可以打个比方来说,一栋大楼里面可以有很多的楼层,每个楼层可能都有不同的公司,这样来考虑,这栋大楼就类似数据文件,楼的每一层就类似一个数据段,每一层比方最多可以有4家公司,一家公司有40个人,有的公司大一点,占用两层,那么就是8个区,320个数据块,有的公司小一点,就占用一层里面的一块,那么这个公司就类似一个较小的数据段,占用1个区,包含40个数据块。
从存储层面来说,目前数据库中只能够查询到区这一级别的信息了。
在user_extents中只能够查看到最基本的区的信息,user_segment里面可以得到一个大体的信息

SQL> desc user_extents
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 SEGMENT_NAME                                       VARCHAR2(81)
 PARTITION_NAME                                     VARCHAR2(30)
 SEGMENT_TYPE                                       VARCHAR2(18)
 TABLESPACE_NAME                                    VARCHAR2(30)
 EXTENT_ID                                          NUMBER
 BYTES                                              NUMBER
 BLOCKS                                             NUMBER

SQL> select extent_id,blocks from user_extents where segment_name='DATA';

 EXTENT_ID     BLOCKS
---------- ----------
         0          8
         1          8
         2          8
         3          8
         4          8
         5          8


SQL> select extents,blocks from user_segments where segment_name='DATA';

   EXTENTS     BLOCKS
---------- ----------
         6         48       

如果想查看每个区中包含哪些数据块,就无能为力了。这个时候dba_extents可以作为一个补充。可以看到哪些区包含哪些数据块。
SQL> select block_id,extent_id,BLOCKS from dba_extents where owner='N1' and segment_name='DATA';

  BLOCK_ID  EXTENT_ID     BLOCKS
---------- ---------- ----------
     12800          0          8
     12808          5          8
      3600          4          8
      5224          3          8
     12672          2          8
     12672          1          8

当然了这个也不能让热满意,有时候想看看一些记录大概占有多大的空间,就可以使用rowid来辅助了。
目前我们得到表data的数据类型如下:
DATA_LENGTH DATA_TYPE
----------- ------------------------------
         10 VARCHAR2
         22 NUMBER
         22 NUMBER
         22 NUMBER
         22 NUMBER
         22 NUMBER
         22 NUMBER
         22 NUMBER
         22 NUMBER
         22 NUMBER
SQL> select sum(data_length) from user_tab_cols where table_name='DATA';

SUM(DATA_LENGTH)
----------------
             208

那么这些数据类型的数据占用的空间是否是按照最大字节208来存储的呢,换句话说就是表里存放着一条记录,可能长度只有number(2),但是是否会依旧占用22个字节来存储呢。
我们随机抽取一个数据块来简单的测试一下。
可以看到如下两条记录是从0开始计数的,都在12803这个数据块中。
select dbms_rowid.ROWID_OBJECT(rowid) object_id,
dbms_rowid.ROWID_RELATIVE_FNO(rowid) file_no,
dbms_rowid.rowid_row_number(rowid) row_no,
dbms_rowid.rowid_block_number(rowid) blk_number
from data  where rownum      OBJECT_ID    FILE_NO     ROW_NO BLK_NUMBER
---------- ---------- ---------- ----------
     18993         11          0      12803
     18993         11          1      12803

我们来进一步查看12803这个数据块中含有哪些记录。不考虑数据块的其他存储参数。按照默认的值来看。
里面含有约148条记录。

 OBJECT_ID    FILE_NO     ROW_NO BLK_NUMBER
---------- ---------- ---------- ----------
。。。。。。
     18993         11        143      12803
     18993         11        144      12803
     18993         11        145      12803
     18993         11        146      12803
     18993         11        147      12803

148 rows selected.

可以得到每条记录的平均大小就是55字节。
SQL> select 1024*8/148 from dual;

1024*8/148
----------
55.3513514

另外需要注意的是,这个rownum,block number可以给予不同的数据文件有不同的含义。
同样一个表中的记录在数据文件5中是数据块12676,在7号数据文件是也含有数据块为12767的。而且对应的数据行数也是重新从0开始计算。
 OBJECT_ID    FILE_NO     ROW_NO BLK_NUMBER
---------- ---------- ---------- ----------
     18993          5        143      12676
     18993          5        144      12676
     18993          5        145      12676
     18993          5        146      12676
     18993          5        147      12676
     18993          5        148      12676
     18993          7          0      12676
     18993          7          1      12676
     18993          7          2      12676
     18993          7          3      12676
     18993          7          4      12676

从上面的小测试可以简单得出:
数据类型的存储是有一定的收缩性的,比如数据类型为number(22),最大支持22位,但是它实际存储的时候会按照实际的存储数据进行分配
另外一个数据段可以存储在多个数据文件中,数据块号为12676在不同的数据文件中有不同的含义,对应的row_number也有不同的意义。
我们可以从user_extents中查看对应的区段信息,可以从dba_extents中得到更多的信息,但是更深入的分析,可以借助rowid来查看,在情况允许的时候,甚至可以导出对应的数据块dump来做底层的分析。

目录
相关文章
|
Oracle 关系型数据库 数据库
Oracle生产数据库insert插入较慢分析过程和解决办法
Oracle生产数据库insert插入较慢分析过程和解决办法
323 0
|
1月前
|
Oracle 关系型数据库
oracle基本笔记整理及案例分析2
oracle基本笔记整理及案例分析2
12 0
|
1月前
|
Oracle 关系型数据库
oracle基本笔记整理及案例分析1
oracle基本笔记整理及案例分析1
17 0
|
6月前
|
Oracle 关系型数据库 Java
分享一个 Oracle RAC 模式下客户端建立JDBC初始连接时因ONS造成应用启动时卡顿30秒问题的排查分析案例
分享一个 Oracle RAC 模式下客户端建立JDBC初始连接时因ONS造成应用启动时卡顿30秒问题的排查分析案例
|
7月前
|
存储 Oracle 算法
数据库数据恢复-ORACLE数据库常见故障的数据恢复可能性分析
ORACLE数据库常见故障: 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE数据库ASM存储破坏。 3、ORACLE数据库数据文件丢失。 4、ORACLE数据库数据文件部分损坏。 5、ORACLE数据库DUMP文件损坏。
|
9月前
|
Oracle 关系型数据库 索引
Toad Oracle Parttion表分析
当一个数据表的数据达到几十亿笔的时候,对整个表做表分析代价较大。
74 0
|
10月前
|
存储 分布式计算 Oracle
大数据数据存储的数据库的关系型数据库之Oracle
在大数据领域,数据库是数据存储的一个重要组成部分。Oracle作为一种强大的关系型数据库,在企业级应用中得到了广泛应用。本文将对Oracle进行介绍。
105 2
|
11月前
|
Oracle 前端开发 关系型数据库
使用隐含参数_disable_logging分析oracle写redo logfile的性能
oracle有一个隐含参数_disable_logging可以禁止日志的生成,这个参数当然不能在生产库使用,但我们可以将其因为与测试,例如,如果我们怀疑数据库写redo logfile存在性能问题,我们可以将这个参数设置为true,禁止写日志,看看oracle的性能提高了多少。
|
11月前
|
SQL 存储 Oracle
Oracle优化07-分析及动态采样-动态采样
Oracle优化07-分析及动态采样-动态采样
97 0
|
11月前
|
存储 Oracle 关系型数据库
Oracle优化07-分析及动态采样-DBMS_STATS 包
Oracle优化07-分析及动态采样-DBMS_STATS 包
86 0
Oracle优化07-分析及动态采样-DBMS_STATS 包

推荐镜像

更多