Oracle基本的数据存储机制---表
表是一种逻辑结构,数据在表中以行和列的形式储存。
-
数据的存储类型
oracle定义了3种数据类型,分别是标量数据类型、集合数据类型和关系数据类型。
-
标量数据类型
VARCHAR2(size)和NVACHAR2(size):变长字符型数据
该数据类型定义数据时,数据的存储区大小是不固定的,依据存储数据的长度(size)进行动态分配存储区。
size的最大值为17000,最小值和默认值都是1
CHAR(size)和NCHAR(size):定长字符型数据,用空格在数据的右边补到固定长度
该数据类型一旦定义,则存储该变量的存储区的大小就固定下来了,显然在存储区分配上不具有动态性。
DATE:日期型数据
日期型数据的取值范围是公元前17712年1月1日到公元9999年12月31日
NUMBER(P,S):数字型数据
参数p指十进制数的中长度,s为十进制数小数点后的位数。
p参数最大值为38,最小值1,s参数的最大值为1217,最小值为-817
CLOB或LONG:用于存储大数据对象,该对象为定长的字符型数据(如学术论文或者个人简历等)。
BLOB或LONG RAW:存储无结构的大对象(如照片,ppt等)。
BFILE:在操作系统文件中存储无结构的二进制对象,oracle无法维护这些数据类型。
RAW:数据类型使得数据库可以直接存储二进制数据,在计算机之间传输该类型数据时,数据库不对该数据类型进行任何转换。
-
集合数据类型
oracle集合数据类型包括嵌套表和VARRY数据类型。在嵌套表的列值中又包含表,嵌套表中的元素数量没有限制。
-
关系数据类型
关系类型REF指向一个对象,在oracle数据库中一个典型的REF类型的对象就是游标cursor
-
行ID(ROWID)
ROWID也是一种数据类型,这种数据类型是oracle服务器使用并管理的。
ROWID是数据库中每一行的唯一标识符
ROWID作为列值是隐式存储的
ROWID不直接给出行的物理地址,但是可以用ROWID进行定位行
ROWID提供了最快速访问表中行的方法
查看scott的dept表的行ID
以下面的操作DEPTNO=20的数据为例,前6位AAAVRC为数据对象号,在数据库中每个对象是唯一的。接着3位AAE是相对应的文件号,它和表空间中的一个数据文件相对应、接着6位的AAAACH位块号,块号相对文件中存储改行的块的位置,最后3位AAB位行号,行号标识块头中行目录的位置。
SQL> select rowid,deptno,dname,loc from dept;
ROWID DEPTNO DNAME LOC
------------------ ---------- ------------------------------------------ ---------------------------------------
AAAVRCAAEAAAACHAAA 10 ACCOUNTING NEW YORK
AAAVRCAAEAAAACHAAB 20 RESEARCH DALLAS
AAAVRCAAEAAAACHAAC 30 SALES CHICAGO
AAAVRCAAEAAAACHAAD 40 OPERATIONS BOSTON
创建表(略)
https://www.cnblogs.com/xielong/p/9121680.html
https://www.cnblogs.com/52xuanxuan/p/6163975.html
创建表时如果不指定用户的名字则默认为当前用户创建的表
段空间管理
我们向表中插入数据、删除数据、修改数据时都会造成段空间的变化,此时段空间的回收和分配就是一个问题。
在oracle 9i之前是手动管理段空间,此时要求用户自己设置参数控制段空间的使用。
现在开始使用自动段空间管理(ASSM),它使用位图来管理段空间的使用情况。如果表空间时ASSM则表中的段自然是ASSM。
理解高水位线(HWM)
对于表段使用术语“高水位线”来标记,使用过的数据块的边界。
对于新创建的表,高水位线位于第一个块,随着时间的推移,这些表段中存入数据,高水位线随之移动。如果删除了表中的数据,此时某些数据块即使没有任何数据但是依然保持高水位线高度。此时发生表重建、截断、SHINK时才会调整高水位线,调整以后的高水位线下的数据块都包含数据。
如果一个超大的表,删除了90%的数据,高水位线没有调整,对表进行全表扫描时候依然会对删除了的数据进行扫描,降低了效率。
如果使用截断而不是delete删除表中所有数据,此时会调整高水位线到表段的第一个数据块。
ASSM(自动段空间管理)中HWM的管理更加细致,对于ASSM,oracle维护着一个低HWM,它的含义是在低HWM之前所有的数据块都是有数据的,而且可以直接读取,而低HWM到HWM之间的所有数据需要慎重对待,这部分数据可能已经格式化,或者未格式化还在使用。
行迁移
行迁移是指某一行数据量过大,导致改行无法存储在创建这一行的数据块中,此时oracle会使得改行离开原来的数据块,存入另一个数据块中,改行的原始块和新块之间使用ROWID来记录变迁关系,使得原来行指导后续存储位置。
但是这种方式使得原本只需要读取一个数据块的数据需要从多个数据块读取或者写入,这样明显增加了I/O时间,并且维护也相对复杂。
创建索引组织表(IOT)
索引组织表将数据和索引存储在一起,按照索引的结构来组织和存储表中的数据。索引组织表的存储结构不是堆组织表,而是按照某个主键排序后存储的,然后再以B数的组织结构存储在数据段中。
索引组织表对于经常使用主键实现查询的事务非常高效,索引组织表的主键约束不能被删除、延期或禁止。
IOT适用的场合有:
完全由主键组成的表。
如果你只会通过一个主键来访问一个表。
数据以某种特定的顺序物理存储。
IOT的好处:如果经常在一个主键或唯一键上使用between查询,也是如此。如果数据非常有序地存储,就能提升这些查询的性能
-
IOT表的结构
创建一个最简单的索引组织表
SQL> create table tiot(
2 x int primary key,
3 y number,
4 z varchar2(20)
5 )organization index;
表已创建。
表参数以及参数维护
在创建表时,我们使用了表空间和storage参数,而在数据库维护过程中,这些参数是不允许变化的,oracle为了管理和控制数据块,引入了17个参数,当手工管理段空间时,需要设置这几个参数。
-
事务槽
事务槽在数据块头中,存储了有关事务的控制信息,而每一行数据有一个锁位,该锁位号和事务槽号相同,数据库服务器就是通过每行的锁位找到数据块头中的事务槽,利用存储在该事务槽中的事务信息完成对该行的操作。
-
INITRANS:该参数控制对数据块的并行操作的参数
INITRANS定义了创建数据块时事务槽的初始值,该值默认为1,如果该参数为2,说明数据库服务器实现在一个数据块中有最多两个并行的事务,每个事务独立并行地通过自己的事务槽实现对该数据的事务操作。
-
MAXTRANS:该参数定义了创建数据块时事务槽的最大值,该参数值默认为255
-
查看SOCTT用户的DEPT'表参数中的INITRANS和MAXTRANS
下面的操作说明了DEPT表中INITRANS与MAXTRANS都采用了默认值
SQL> select ini_trans,max_trans from dba_tables where owner='SCOTT' and table_name='DEPT';
INI_TRANS MAX_TRANS
---------- ----------
1 255
-
PCTFREE:该参数用于设置每个数据块中预留空间的百分比数,当数据块需要额外的空间时,使用PCTFREE参数设置的空间。默认值为10%
-
数据块结构
数据块由三部分组成,数据块头,空闲区和数据区。
其中数据块头从上往下增长,数据区从下往上增长,二者“碰头”则空闲区被占满。
一旦空闲区满,后续的操作(如修改数据,增加了数据量),就需要占用数据空间,此时该数据块中就无法满足要求,这样就造成了占用其他数据块的空间,会造成系统I/O效率低下,oracle设计了PCTFREE参数在每个数据块中设置空闲区域,满足数据操作时对数据块空间的要求。
-
FREELISTS:该参数是一个空闲数据块队列的列表,当用户向表中插入数据时,需要数据块作为储存空间,该参数中的数据块就作为候选的数据块。
-
PCTUSED:该参数定义了数据块中已经使用了的空闲区的百分比数,只有当该数据块中已经使用的空间的百分比低于这个参数时,该数据块才放入段中的空闲数据块列表,该参数默认为170%。
SQL> select table_name,tablespace_name,pct_free,pct_used from dba_tables where table_name='DEPT';
TABLE_NAME TABLESPACE_NAME PCT_FREE PCT_USED
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------ ---------- ----------
DEPT USERS 10
SQL> alter table scott.dept pctused 50 pctfree 30;
表已更改。
维护列
向表中新增一列
SQL> alter table scott.dept add(
2 sex char
3 );
表已更改。
修改列
SQL> alter table scott.dept modify(
2 sex varchar2(2)
3 );
表已更改。
删除列
SQL> alter table scott.dept drop column sex;
表已更改。
设置无用列
SQL> alter table scott.dept set unused column sex;
表已更改。
删除无用列
SQL> alter table scott.dept drop unused columns;
表已更改。
更改列名
SQL> alter table scott.dept add (
2 sex char
3 );
表已更改。
SQL> alter table scott.dept rename column sex to gender;
表已更改。
删除和截断表
截断表
如果不需要表中的数据,可以使用TRUNCATE来截断一个表,使用截断表的时候,只删除表中的数据,但是会保留表中的结构,还是可以用INSERT插入数据
SQL> create table scott.abc as select * from scott.emp;
表已创建。
SQL> create table scott.abc as select * from scott.emp;
表已创建。
SQL> select * from scott.abc;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ------------------------------ --------------------------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12¿ -80 800 20
7499 ALLEN SALESMAN 7698 20-2¿ -81 1600 300 30
7521 WARD SALESMAN 7698 22-2¿ -81 1250 500 30
7566 JONES MANAGER 7839 02-4¿ -81 2975 20
7654 MARTIN SALESMAN 7698 28-9¿ -81 1250 1400 30
7698 BLAKE MANAGER 7839 01-5¿ -81 2850 30
7782 CLARK MANAGER 7839 09-6¿ -81 2450 10
7788 SCOTT ANALYST 7566 19-4¿ -87 3000 20
7839 KING PRESIDENT 17-11¿ -81 5000 10
7844 TURNER SALESMAN 7698 08-9¿ -81 1500 0 30
7876 ADAMS CLERK 7788 23-5¿ -87 1100 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ------------------------------ --------------------------- ---------- -------------- ---------- ---------- ----------
7900 JAMES CLERK 7698 03-12¿ -81 950 30
7902 FORD ANALYST 7566 03-12¿ -81 3000 20
7934 MILLER CLERK 7782 23-1¿ -82 1300 10
已选择14行。
SQL> truncate table scott.abc;
表被截断。
SQL> select * from scott.abc;
未选定行
删除表
SQL> drop table scott.abc;
表已删除。
SQL> select * from scott.abc;
select * from scott.abc
*
第 1 行出现错误:
ORA-00942: ¿¿¿¿¿¿¿