<Oracle基本的数据存储机制-表>

来源:互联网 发布:mac er图 编辑:程序博客网 时间:2024/06/02 04:18

表是Oracle数据库中最基本的数据存储结构,是一种逻辑结构,建议大家去读一些关于sql的书籍一般都有提到一些基本的概念,这里就不做详细讲解了。为了后面的内容继续,我在这里只做简单的提及。

     Oracle的数据类型:

数据的存储类型:标量数据类型、集合数据类型和关系数据类型。

1 > 标量数据类型:

               VARCHAR2(szie)/NVARCHAR2(size): 它们的size默认为1,最大为4000,都是变长字符型数据,它会依据存储数据的长度进行动态分配存储区,定义该数据类型是需要指定长度,后者是它支持全球化数据类型,支持定长和变长字符集。

              CHAR(szie)/NCHAR(szie) : 该数据类型一旦定义,则存储变量的存储区的大小就固定下来。最小和默认SZIE为1,最大为2000.

              DATE: Oracle服务器使用7个定长的存储区存储日期类型数据,它可以是月、年、日、时、分、秒。范围是公元前4712年1月1日到公元9999年12月31日。

              NUMBER(p,s) : 参数p指十进制数中的长度,s为小数点后位数,p最大为38,最小为1,s最大为124 ,最小为-84。

             CLOB或LONG:用于存储大数据对象,该对象为定长的字符型数据,如论文等,对于clob数据类型的列的操作不能直接使用Oracle数据库指令,需要一个DBMS_LOB的PL/SQL软件包来维护该数据类型的列。

              BLOB 或LONG RAW:存储无结构的大对象,如相片、ppt等,bolb也需要DBMS_LOB来实现。

              BFILE:在操作系统文件中存储无结构的二进制对象,它是一个Oracle外部数据类型,必须有操作系统来维护。

              RAW:可以直接存储二进制,在计算机之间传输此类型数据时,数据库不需要做任何类型转换,所以存储和传输效率较高,最大长度为2000个字节。

  (注:long 和 long raw是Oracle8以前的用的,现在LONG 数据类型完全可以用clob 和blob数据类型替换)           

2 >集合数据类型:

              Oracle集合数据类型包括嵌套表和VARRY数据类型。在嵌套表的列值中又包含表,嵌套表中的元素数量没有限制,当然不能超过表所在的表空间,VARRY中的元素是有数量限制的。

3 >关系数据类型

              REF指向一个对象,Oracle中常用的就是游标了cursor。

以上就是我们常用的存储类型了。

贴士:

在讲述建表前我们来解释下Oracle常用的rowid的含义,概念:它是数据库中每一行的唯一标识符,作为列它是隐式存储的,不直接给出行的物理地址,但是可以用它来定位行,提供了最快速的访问表中行的方法。前6位为数据对象号,在数据库中每个对象都是唯一的。接着三位为相当文件号,它和表空间中的一个数据文件对应。接着4位为块号,块号为相对文件中存储该行的快的位置,最后三位为行号,行号标识块头中行目录的位置,而使用该行目录的位置可以找到行的起始地址,这个了解即可 不需要深究。

 

建表

标准:命名简单,但具有具体的含义;每个表都有一个表空间,这样便于管理和维护;使用EXTENT尺寸减少表空间碎片;表名最大字符30个。

创建一个普通表:

------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL>CREATE TABLE scott.temp_emp(emp_id numebr(4),ename varchar2(30),emp_sex char) TABLEspace users;

------------------------------------------------------------------------------------------------------------------------------------------------------------------

一旦使用DDL语句创建了表对象,对象的信息如表名,表存储的表空间等将记录在数据字典中,数据字典后期再说,数据字典表 dba_tables中可以看到传教的表。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL>select owner,table_name, tablespace_name from dba_tables where owner='SCOTT';

------------------------------------------------------------------------------------------------------------------------------------------------------------------

创建表的时候如果不指定表用户和空间则默认为当前用户和空间创建该表。

在创建表的时候,Oracle推荐一个表最好放在一个表空间而且该表空间是本地管理的(减少维护数据字典的负担),所以假如我们已经创建了一个本地的表空间,可以使用更多的参数在本地管理表空间中创建的表,如何创建一个表空间呢?

------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL> create TABLEspace lin datafile 'd:\temp\lin.dbf' size 30M extent management local uniform size 1M;

       表空间已创建。

SQL>CREATE TABLE scott.temp_emp(emp_id numebr(4),ename varchar2(30),emp_sex char)

      2   storage(inital 100k next 100k pctincrease 0 minextents 1 maxextents 8)

      3   TABLEspace lin;

      表已创建。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

storage中 initial指该表数据量增加时,需要的自动分配磁盘空间第一次分配为100K,第二次也是100K,所分配的最大磁盘为8个extends。最小为1个,pctincrease是一个权值参数,从第三次开始按规则计算:next*(1+pctincrease/100)的(n-2)次方,其中n>=3。

验证表是否创建成功

------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL> select table_name,tablespace_name,initial_extent,next_extent

2          from dba_tables where owner ='SCOTT' and table_name='tmp_emp';

table_name                         tablespace_name           initial_extent              next_extent

--------------------                  ----------------------------          ---------------          --------------------------

    tmp_emp                                   LIN                                102400                    1048574

------------------------------------------------------------------------------------------------------------------------------------------------------------------

创建临时表:

               它是一个非常特殊的表,只对当前用户的当前会话有效。目的就是是的某些操作效率更高,临时表中的数据时当前会话的私有数据,当前会话只操作自己的数据,没有数据锁的征用,这极大提高了临时表操作的效率。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL> create global temporary table

2          SCOTT.emp_temporary on commit preserve rows as

3          select  *  from scott.emp where job = 'MANAGER';

表已创建。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

这种临时表删除切记要先关闭当前session 然后再去删除。

验证是否成功创建了临时表

------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL> select owner,table_name,tablespace_name

2        from dba_tables

3        where table_name='EMP_TEMPORARY';

OWNER                          TABLE_NAME                     TABLESPACE_NAME

------------------------           ----------------------------                 -----------------------------------

SCOTT                         EMP_TEMPORARY

------------------------------------------------------------------------------------------------------------------------------------------------------------------

 切记如果你查不出来请核对下你的表名是否大写了,由上可知临时表默认是不放在表空间中的,也不存放在临时表空间中,而是存储在临时段中,他是一个磁盘区,当SQL语句执行查询时,如果需要对返回的数据进行排序,oracle首先需要在内存完成排序工作,如果内存容量不够,就需要把计算的中间结果放在临时段中。

查看创建的是否为临时表

------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL>select table_name,tablespace_name,temporary

2       from dba_tables

3       where  owner='SCOTT'

4       and   table_name='EMP_TEMPORARY';

TABLE_NAME                          TABLESPACE_NAME                     TEMPORARY

----------------------------           ------------------------------------------------------       -----------------------

EMP_TEMPORARY                                                                                Y

------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

查询临时表输出结果 

------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

 

SQL> desc SCOTT,EMP_TEMPORARY

名称                                      是否为空?      类型
-----------------------------------------    -------         -------------------
U_ID                                                         NUMBER
U_NAME                                                 VARCHAR2(40)

------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

 

段空间管理(这个地方比较乏味 因为都是概念 知道就好)

段空间管理不仅仅是指表段的空间管理,其他段数据都需要自己的段管理方式,段是oracle的一个逻辑结构,表段是最常用的一类段,但我们向表中插入数据、删除数据时以及修改数据时都会造成段空间变化,此时段空间的回收和分配就是一个问题,在9i之前oracle都是手动段空间管理,此时需要用户自己设置FREELIST、PCTUSED、PCTFREE等参数。9i以后开始使用自动段空间管理(ASSM),它使用位图来管理段空间的使用情况。如果表空间ASSM,则表空间中的段自然也是ASSM。在ASSM中FREELIST、PCTUSED都被忽略,手工段空间管理的MAXTRANS参数在10g中被所有段忽略。

HWM(高水位线)

对于表段使用属于“高水位线”来标记使用过的数据块的边界对于新建的表,高水位线位于第一个块,随着时间的推移,这些表段中存入数据,高水位线会随之移动。如果删除了表中的数据,此时某些数据块即使为空,如果对表进行全表扫描,此时依然保持高水位线的高度,但是在发生表重建、TRUNCATE以及SHINK时会调整高水位线,调整后的高水位线下的数据块都包含数据。使用truncate 而不是使用 delete删除表中的所有数据,此时会调整高水位线到表段的第一个数据块。

行迁移

是指某一行的数据量过大,导致该行无法存储在创建这行的数据块中,此时oracle就会使得该行离开原来的块,存储到另一个块中,该行的原始块和新块之间使用rowid记录这种变迁关系,使得原始行知道后续数据存储的位置。所以如果某行插入的数据过大,导致该行即使通过空闲空间合并也无法放下新插入的数据,此时oracle就考虑使用行迁移,将无法放下的行数据插入到新的数据块中,虽然可行,请尽量避免。

索引组织表(IOT)

它是一个特殊的表,它将数据和索引存储在一起,安装索引的结构来组织和存储表中的数据。它的存储结构不是堆组织表。堆中数据时无序的,而索引组织表中的数据是按照某个主键排序后存储的,然后再以B tree的组织结构存储在数据段中。索引组织表对于经常使用主键字段来实现查询的事物非常高效,索引组织表的主键约束不能被删除、延期和禁止。它使用的场合

           完全由主键组成的表。这样的表如果采用堆组织表,则表本身完全是多余的开销,因为所有的数据同样也保存在索引里,此时堆表是没用的。

           如果你只会通过一个主键来访问一个表,这样的表也比较合适。

           数据以某种特点的顺序物理存储,如果经常在一个主键或唯一键上使用between查询,也是如此。

下面就从一个实例来简单介绍 IOT 表的结构

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL> create table tiot

2        (x int primary key,

3         y number,

4         z varchar2(20))

5         organization index;

表已创建。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

查看创建的表

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL> select DBMS_METADATA.GET_DDL('TABLE','TIOT') FROM DUAL;

          DBMS_METADATA.GET_DDL('TABLE','TIOT')

       -----------------------------------------------------------------------------------

        create table "SYS","TIOT"

        (    "X"  NUMBER(*,0),

             "Y" NUMBER,

             "Z" VARCHAR2(20),

             PRIMARY KEY("X") ENABLE

          )ORGANIZATION INDEX NOCOMPRESS PCTFREE 10 INITRANS 2 MAXTRANS 255 LOGGING STORAGE

     (INITIAL 45534 NEXT 1048574 MINEXTENTS 2147483445 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS1 BUFFER_POOL DEFAULT)

     TABLESPACE "SYSTEM"

     PCTTHRESHOLD 50 

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

注意:创建IOT时,必须要设定主键,否则报错,索引组织表实际上将所有数据都放入了索引中。

ORGANIZATION INDEX :说明这是一个索引组织表

OVERFLOW:允许我们创建一个新段,如果IOT的行记录太大,则可以存储到这个新段上去。那么什么时候使用这个新段就要去看PCTTHRESHOLD和INCLUDING这两个参数。

INCLUDING:行中从第一列直到INCLUDING所指定的列的所有列数据都存储在索引块上,其余列存储在溢出段上。

PCTTHRESHOLD:如果行中的数据量超过了数据块大小的百分比,行中其余的数据就要放入溢出段了。

COMPRESS:和普通的索引一样,索引组织表也可以使用COMPRESS子句进行键压缩以消除重复值。具体的操作时,在 organization index之后加上COMPRESS,n的意义在于指定压缩的列数,默认无穷大。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL> create table iot_test

2        (x int,

3         y number,

4         z varchar2(20),

5         constraint iot_test_pk primary key(x)

6            )

7          organization index

8          prcthreshold 10

9          including y

10        overflow tablespace users;

表已创建。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以上组织索引表大家可是尝试一下

下面就讲讲表参数以及参数维护:

Heap Table 就是一般的表,获取表中的数据时按命中率来得到的。没有什么明确先后之分,在进行全表扫描的时候不是说先插入的数据就先获取,数据存放是随机的,当然根据可用空闲的空间决定。

IOT 就类似是一个全是索引的表,表中所有子都放在索引上,所以就等于约定了数据存放的时候是按照严格规定的,在数据插入以前其实就已经确定了数据的顺序,所以不管插入先后顺序,都没关系,当然插入数据的时候就稍微慢些。在创建表的时候我们用到的表空间和storage参数,如initial、next、pctincrease 等,而在数据库维护过程中,这些参数是不允许变化的,但是oracle管理器和控制块,引入了4个参数,当使用手工管理进行段空间管理时需要设置一下几个参数:

INTRANS:是控制对数据块并行操作的参数(这里介绍一下事物槽的概念:事物槽在数据块头中,存储了有关事务的控制信息,而每行数据都有一个锁位,该锁位号和事物槽号相同,数据块服务器就是通过每行的锁位找到数据块头中的事物槽,利用存储在该事物槽中的事务信息完成对该行数据的操作。每个事务只使用一个事物槽)定义了创建数据块时事物槽的初始值,该参数默认值为1,如该参数为2,说明数据库服务器实现在一个数据块中可以有最多2个并行的事务,每个事务独立地并行通过自己的事物槽还实现对该行数据的事务操作。

 

 

 

这些东西知道就可以了有个概念不必深究。下面讲的东西希望大家都能熟练使用。当然如果说的不对的希望读者能给出指正,相互学习。

 

 

 

 

 

 

 

 

 

 

 

 

0 0
原创粉丝点击