管理和维护表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qqww120102/article/details/78054030


一、在Oracle数据库中“表”是什么?
表在Oracle数据库中是最基本、最常用的存储数据的逻辑存储结构,管理和维护表在数据库设计、维护都有很重要的应用。
数据在表中以行和列的形式存储,在创建表的时候需要设定表名、表内各列的列名和各列的数据类型及数据宽度,同一行的所有信息叫记录。
二、数据的存储类型
Oracle共定义3种数据类型,分别为标量数据类型、集合数据类型、关系数据类型
1、标量数据类型
常见包括CHAR、VARCHAR2、DATA、NUMBER等类型
2、集合数据类型
包括嵌套表和VARRY类型
3、关系数据类型
关系数据类型REF指定一个对象,Oracle中最典型的REF类型就是游标(cursor)
4、行ID(ROWID)
行ID也是一种数据类型,是Oracle服务器使用并管理。行ID的特性包括:
1、Oracle数据库每一行的唯一标识
2、作为列值隐式存储
3、不能直接给出物理地址,但可以通过行ID进行数据行的定位
4、行ID是最快访问表内数据的方式

三、创建表
Oracle创建表的规则
1、命名尽量简单,表名要具有一定的意义,即表名要清楚描述表中数据的数据内容
2、每个表一个表空间,易于管理和维护。对一个表空间的维护不影响其他的表,并且采用本地管理表空间,减少数据字典的维护和记录数据量。
3、使用标准extent尺寸减少表空间碎片
4、Oracle允许表名的最大长度为30个字符

1、创建普通表
普通表使用CREATE TABLE指令创建,属于DDL语句。通过dba_tables数据字典查看表的相关参数

SQL> create table scott.employees
2 (ecode number(17),
3 ename varchar2(25),
4 eaddress varchar2(30),
5 ephone varchar2(15))
6 storage (initial 100k next 100k pctincrease 0 minextents 1
7 maxextents 8)
8 tablespace users;

SQL> select table_name,tablespace_name,initial_extent,next_extent,pct_free,pct_used,pct_increase
2 from dba_tables
3 where owner='SCOTT' and
4 table_name='EMPLOYEES';


TABLE_NAME TABLESPACE_NAME INITIAL_EXTENT NEXT_EXTENT PCT_FREE PCT_USED PCT_INCREASE
---------------- ------------------------ ---------------------- ---------------------- -------------- -------------- ------------------
EMPLOYEES USERS 106496 106496 10 40

INITIAL_EXTENT ----------------------初始区段分配的大小
NEXT_EXTENT ----------------------第二次分配区段的大小
PCT_FREE ---------------------数据块剩余容量达到脱离自由链表的百分比,自动管理可不设置。默认10% 与表空间参数相同
PCT_USED ---------------------数据块剩余容量达到加入自由链表的百分比,自动管理可不设置。默认40% 与表空间参数相同
PCT_INCREASE ---------------------第三次及以后分配区段的大小,利用计算公式进行区段递增。设NEXT_EXTENT=100K,PCT_INCREASE=50 ,那么第三次增加区段为100 x(100%+50%)=150K,第四次增加区段则为150 x(100%+50%)=225K,后面以此类推。

2、创建临时表(特殊)
临时表是特殊的表,共分为会话级和事务级(默认)。
该表有以下特点:
1、只对当前用户的当前会话有效(会话级)或只对当前用户当前会话的当前事务有效(事务级),临时表内数据只对当前用户当前会话可见,退出后临时表自动变为可见不可用,并将表内数据TRUNCATE(截断),但数据字典定义并不清除。
2、只对应当前用户当前会话,不会产生DML锁的争用
3、临时表内的数据不会备份,恢复,对其表结构的修改也不会有任何日志信息(NOLOGGING)
4、尽管临时表的DML操作速度比较快,但同样也是要产生 Redo Log (当前UNDO会产生,退出后自动删除)只是同样的DML语句,比对 PERMANENT 的DML 产生的Redo Log 少
5、临时表可以创建临时的索引、视图、触发器
6、如果要DROP会话级别临时表,并且其中包含数据时,必须先TRUNCATE其中的数据。否则会报错。
7、不支持主外键关系
8、临时表不能永久的保存数据。
9、系统临时表空间为空,不能创建临时表
10、不支持lob 对象,支持大对象与不同版本有关

创建方法:

会话级别临时表 On Commit Preserve Rows(当前用户当前会话退出时自动truncate)
事务级别临时表 On Commit Delete Rows(当前用户当前事务commit或rollback,自动truncate)

删除方法:

TRUNCATE TABLE table_name 会话级别需要先截断数据,然后才能DROP
DROP TABLE table_name | purge |
drop table table_name; 删除表 表会改名进回收站
drop table table_name purge; 不经过回收站直接删除
purge recyclebin; 清空回收站

测试创建一个会话级别临时表
SQL> create global temporary table
2 scott.emp_temporary
3 on commit preserve rows
4 as
5 select *
6 from scott.emp
7 where job = 'MANAGER';

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

使用后首先truncate,然后drop
SQL> truncate table scott.temp_employees;

Table truncated.

SQL> drop table scott.temp_employees purge;

Table dropped.

参考SCOTT用户的EMP表JOB列为MANAGER员工的所有信息,创建EMP_TEMPORARY临时表
通过DBA_TABLES查看可以看出,临时表不属于任何表空间。TEMPORARY为Y代表此表是临时表。实际上临时表存在于临时段中,在临时段内分配一块区域进行使用。(临时段是一个磁盘排序区(类似于swap或交换分区),主要作用是 当用户使用SQL语句进行查询操作时,如果需要对返回结果进行排序时,首先在内存中进行排序工作,如果内存容量不够完成全部排序操作,就需要临时段进行排序)

四、段空间管理
(本章具体参数可查看表空间管理和创建章节中自动段空间管理章节)
段空间管理不仅指表段的空间管理,其他段数据都需要自己的段管理方式。段是Oracle一个逻辑结构,表段是最常用的一类段,但我们向表中插入数据、变更或者删除数据时都会造成段空间的变化,段空间的回收和分配就是一个需要解决的问题。
在Oracle 9i 920以前,使用的是手动段空间管理,此时完全需要手动控制FREELIST、PCTUSED、PCTFREE等参数,通过这些参数控制段空间的使用。
Oracle 920开始使用ASSM自动段空间管理,使用位图来管理和使用段空间。在ASSM中FREELIST、PCTUSED参数都被忽略,手工段空间管理的MAXTRANS(数据块最大并行访问量)在Oracle 11g中也被忽略。

五、理解高水位线(HWM)
高水位线是一句术语,表示使用过的数据块的边界或上限。
新建的表第一个块就是它的高水位线,随着新数据的插入不断将高水位线提高。当使用DML操作删除数据后,虽然数据块的定义已经为空可以重新写入数据,但高水位线并不会下调。只有使用drop(删除定义)、truncate(收缩至初始段大小)、shink(HWM调整,类似于碎片整理)等DDL语句强制高水位线下调,才会将HWM降低。使用ASSM能够实现段空间的自动管理,使段空间HWM保持一个比较低的高度。能够提高数据检索的速度和占用磁盘的空间容量。

六、理解行链接和行迁移(Row Chaining and Migrating)
行链接是指当用户往数据库中执行插入(insert)操作时,这行数据很大,以至于一个数据块都放不下 一整行数据。此时Oracle会把一行数据分为几段存放在数据块中,这个过程叫做行链接(Row Chaining) 。再次读取数据块时,需要将链接的数据块全部读取。这样会增加I/O的读取压力,会产生额外的I/O开销。
行迁移是指某一行的数据通过update更新这行数据,数据量过大,导致该行所在的数据块无法储存更新的全部数据。此时Oracle会使该行数据离开原数据块,存储到另一个数据块中。此时Oracle会在原数据块中保留一个“指针”,这个“指针”指向新的数据块,被移动的数据行的ROWID保持不变,这种数据行的变迁叫做行迁移(Row Migrating)。使得需要查询该行要先查询原始块然后才能知道新块的位置,降低查询和更新数据的效率增加I/O时间,并且由于原本读取一个数据块即可,但是发生行迁移需要读取两个或两个以上的数据块,这种跨行存储数据会增加维护的复杂性,多个行链势必造成维护的开销。对于大量用户并发操作数据行时,由于多余的I/O读取以及数据块在内存内产生多余的LARCH(闩)争用,造成该数据行的访问速度明显下降。
行链接在读取数据时,不论全表扫描还是索引读取都需要将所有数据块全部读取。
行迁移在读取数据时,执行索引读取。由于索引记录的是数据行的地址,当读取后发现只是一个新块的”指针“会再次读向新块,所以会收到影响。但是全表扫描时,原块的地址会忽略。读取时直接读向新块,所以不会对全表扫描有压力。
无论是行链接还是行迁移,都会影响数据库的性能。Oracle在读取这样的记录的时候,Oracle会扫描多个数据块,执行更多的I/O。合理设计和使用合适的表空间、表结构,能够提高数据库的性能。




七、创建索引组织表(IOT)
索引组织表是Oracle提供的一种特殊类型的表,它 将数据与索引存储在一起。 按照索引的结构来组织和存储表中的数据。索引组织表的存储结构不是堆表,我们知道堆表中数据的存储是无序的,而 索引组织表中的数据是按照某个主键排序后存储的,然后再以B树的组织结构存储在数据段中。
索引组织表对于经常使用主键字段来实现查询的事务非常高效,索引组织表的主键约束不能被删除、延期或禁止。使用IOT表由于其索引与数据合二为一的特殊结构带来很多好处,如IOT节约了磁盘空间的占用,大幅度降低了I/O的数据量,少读数据就减少buffer cache中数据块的数量,从而减少数据块在内存中产生的LARCH争用。
IOT适用环境:
1、完全有主键组成的表,这样的表如果采用堆表,则表本身完全是多余的开销,因为所有的数据全部同样也保存在索引里。此时,堆表时没用的。
2、只会通过主键来访问的表,这种表完全适合使用IOT表
3、数据以某种特定的顺序物理存储,IOT就是一种合适的选择。
IOT能够提供以下好处
经常在一个主键或唯一键上使用between查询,如果数据有序的物理存储,就能提高这种查询的速度。

创建IOT表,查看IOT表的表结构
SQL> create table iot_test
2 (x int,
3 y number,
4 z varchar2(20),
5 constraint iot_test_pk primary key(x) ------------------------X列为主键
6 )
7 organization index ------------------------表示这是一张索引组织表
8 pctthreshold 10 ------------------------表示PCT的阈值为10%,超过阀值存储到溢出段
9 including y ------------------------表示由y列开始存储到溢出段
10 overflow tablespace users; ------------------------表示溢出段在users表空间内进行创建


通过DBMS_METADATA包查询表的DDL定义
1、如果使用sqlplus需要进行下列格式化,特别需要对long进行设置,否则无法显示完整的SQL
2、参数要使用大写,否则会查不到
set linesize 180
set pages 999
set long 90000

select dbms_metadata.get_ddl('TABLE','IOT_TEST','SYS') from dual;

DBMS_METADATA.GET_DDL('TABLE','IOT_TEST','SYS')
--------------------------------------------------
CREATE TABLE "SYS"."IOT_TEST"
( "X" NUMBER(*,0), "Y" NUMBER,"Z" VARCHAR2(20), CONSTRAINT "IOT_TEST_PK" PRIMARY KEY ("X") ENABLE)
ORGANIZATION INDEX NOCOMPRESS PCTFREE 10 INITRANS 2 MAXTRANS 255 LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLA SH_CACHE DEFAULT)
TABLESPACE "SYSTEM"
PCTTHRESHOLD 10 INCLUDING "Y" OVERFLOW
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"


IOT表创建相关参数解释

ORGANIZATION INDEX:说明这是一个索引组织表
OVERFLOW:允许创建一个溢出段(overflow segment),如果IOT的行记录太大,则可以存储到这个新段中。什么时候使用新段,由PCTTHRESHOLD和INCLUDING两个参数决定。
INCLUDING:指定由第一列至第N列的数据存储在索引块上,其余存储在溢出段中。
PCTTHRESHOLD:数据块存储数据行容量百分比的阈值,超过阈值的数据存储在溢出段中。
COMPRESS(键压缩):与普通索引一样,索引组织表也可以使用COMPRESS子句进行索引键压缩,用来消除重复值。在 organization index后面加上COMPRESS n子句,n代表指定压缩的列数,默认为无穷大。

八、数据块的结构和管理
为了更好的理解表参数首先解释一下,Oracle中数据块的结构。
1、使用数据块的目的
Oracle为了更方便、快速的对数据文件(datafile)进行管理,提出了Oracle数据块(block)的概念。数据块是Oracle中最小的数据单位,同时也是一种逻辑单位。操作系统的最小物理单位是字节(bytes),每种操作系统都有一个块容量(block size)参数,决定操作系统的数据块大小。Oracle访问时直接访问Oracle数据块,而不是访问操作系统的数据块。
Oracle数据库中共可以定义1种标准块(data block)和5种非标准块(non standard block size)。数据块容量为操作系统块的整倍数,同时小于不同版本数据库数据块的最大限制,这样能够减少不必要的I/O操作。一般为2~32KB

2、数据块的结构
数据块简单分为3个部分:数据块头部、空闲区和数据区
详细分为5个部分:块头(header/Common and Variable),表目录(Table Directory),行目录(Row Directory),自由空间(Free Space)和行数据(Row Data)五部分组成
数据块头部信息区:一般将块头、表目录、行目录归类为数据块头部信息区,头部信息区不存放数据,存放整个数据块的相关信息,这个区域是可变的。一般大小介于84bytes~107bytes之间。
数据块头(header):记录数据块所属segment的类型(数据或索引)、数据块所属的地址、ITL事务槽(记录行数据的事务是否commit)等信息。
表目录:记录块中数据行所在表的表信息,包括所在的表所在表空间、表的地址等信息。
行目录:记录块中数据行相对于起点的偏移量,Oracle正是通过行目录找到所需的数据行。
自由空间:自由空间是一个块中未使用的区域,用于新数据行的插入和已有数据行的更新。
行数据:真正存放表或索引数据的地方,这部分是已经被数据行占用的空间。一个数据行可以跨越多个数据块存储。

数据块的管理

1、事务槽:数据槽记录信息包含4个部分,事务ID、事务所占用的UNDO块地址、事务对应的SCN号、事务是否提交。
事务槽记录事务的数量由INITRANS和MAXTRANS两个参数决定。initrans决定数据块事务槽的初始数量默认为1,maxtrans决定数据槽最大数量默认为255。每个事务只使用一个事务槽,事务槽内的事务提交或回滚后,才可以被其他事务覆盖,当新事务发现没有可用事务槽时,会动态创建一个新的事务槽。每个事务槽与数据行上的锁位号,完全相同。数据库服务器就是通过数据行上的锁位号找到数据块头中对应的事务槽,利用存储在事务槽中的事务信息完成对该行数据的操作。
2、自由空间的管理:手动管理和自动管理
当执行insert操作时,块中的自由空间会减少。当对已经存在的数据行执行update的时候(增加记录长度)时,自由空间也会减少。
当对数据行执行delete和update(减少记录长度)时,块中的自由空间会增加。但是增加的空间不一定是连续的,通常情况下Oracle不会主动将块中不连续的自由空间进行合并,因为合并操作会对数据库性能产生影响(合并过程中需要对数据行进行锁定,造成数据行无法读取)。只有当用户进行insert和update(增加记录长度)操作,找不到连续自由空间时候,Oracle才会合并数据块中不连续的空间。这样有大量碎片的数据块会对数据库的性能产生影响,所有Oracle提出了两种数据块空闲区域的管理方式。

自动管理:通过使用位图(bitmap)来管理和跟踪数据块的使用,能够使管理更加方便、减少碎片和能够使段空间进行自动实时调整。
手动管理:可以通过PCTFREE和PCTUSED两个参数来调整空闲区域,在CREATE或ALTER表空间中进行设置。相比于自动管理,手动管理比较麻烦、不能做到实时调整并且容易造成空间浪费。PCTFREE:指定块内自由空间保留的最小百分比,超过这一数值将该块脱离段空间自由列表( Free List)不允许分配新的事务 。PCTUSED:指定块内自由空间剩余的最大值,超过这一数值将该块加入自由列表(Free List)允许分配新的事务。
九、表的参数及参数维护
heap table(堆表)是普通的表,获取表中数据是按照命中率来得到的。堆表中没有先后之分,是无序的状态。进行全表扫描的时候,并不是先插入就会先获取。数据的存放也是随机的,根据空闲空间进行决定。IOT就是类似于全是索引的表,表中所有字段都存放在索引上。在数据进行插入前就确定了数据插入的顺序和规则,当数据插入时严格执行规则,插入的数据就和索引表一样全都是有序的。这样的好处是在读取数据时能够减少读取block降低I/O,同时能够减少buffer cache的中数据块的数量减少争用。但在数据插入的时候会比普通表要慢一点。
在创建表时,使用了表空间和storage参数,如initial、next、pctincrease等。数据库维护过程中,这些参数不允许变化,但是Oracle为了管理和控制数据块,引入了17个参数。通过前面章节已经知道了数据块的结构了,下面来了解使用手工管理段空间管理时,需要设置几个参数。
INITRANS:事务槽初始数量
MAXTRANS:事务槽最大数量
PCTFREE:保持Free List需要最低的Free Space占总空间百分比
PCTUSED:加入Free List需要的最低Free Space占总空间百分比

测试修改表相关参数
1、查询在第三章'SCOTT’用户下创建的EMPLOYEES表参数设置
SQL> select table_name,tablespace_name,pct_free,pct_used
2 from dba_tables
3 where owner='SCOTT'
4 and table_name='EMPLOYEES';

TABLE_NAME TABLESPACE_NAME PCT_FREE PCT_USED
-------------------- ----------------------------- ----------------- ----------------
EMPLOYEES USERS 10 40
2、利用ALTER指令修改PCT_FREE和PCT_USED参数
SQL> alter table scott.employees
2 pctfree 30
3 pctused 50;

Table altered.
3、再次查询表参数
SQL> select table_name,tablespace_name,pct_free,pct_used
2 from dba_tables
3 where owner='SCOTT'
4 and
5 table_name='EMPLOYEES';

TABLE_NAME TABLESPACE_NAME PCT_FREE PCT_USED
-------------------- ----------------------------- ----------------- ----------------
EMPLOYEES USERS 30 50
由于这样会改变table所占用block在segment内free list的脱离和加入,会对数据块的insert、update以及合并数据块时会对事务产生影响。在没有做测试的情况下,不能轻易对这些默认参数改变。
十、列的维护
在生产情况下,往往需要对已建好的表进行列的修改(增加、删除、改名等),由于很多业务直接都有联系这样改变会对业务产生影响,但是如果重建表显然不太现实。这就需要对列进行维护,利用第三章创建好的EMPLOYEES表,进行修改练习。
1、为EMPLOYEES表插入一条数据
SQL> insert into scott.employees
2 (ecode,ename,eaddress,ephone)
3 values
4 (1,'Tom','address1',8085173170);

1 row created.

2、向表内增加性别列(EXP)和学位列(DEGREE)
SQL> alter table scott.employees
2 add (sex char(1),degree varchar2(10));

Table altered.

3、查看表的列是否增加,和通过update对之前插入的数据进行更新使SEX列和DEGREE列也有数据
select * from scott.employees;

ECODE ENAME EADDRESS EPHONE SEX DEGREE
---------- -------------- ------------------- ----------------- ---------- ---------------
1 Tom address1 8085173170

SQL> update scott.employees set
2 sex='m',degree='Bachelor'
3 where ename='Tom';

1 row updated.

select * from scott.employees;

ECODE ENAME EADDRESS EPHONE SEX DEGREE
---------- -------------- ------------------- ----------------- ---------- ---------------
1 Tom address1 8085173170 m Bachelor

4、将表中的DEGREE列约束设置为NOT NULL
SQL> alter table scott.employees
2 modify
3 (degree varchar2(10) not null);

Table altered.

SQL> desc scott.employees;
Name Null? Type
------------------- ---------------- -----------------------
ECODE NUMBER(17)
ENAME VARCHAR2(25)
EADDRESS VARCHAR2(30)
EPHONE VARCHAR2(15)
SEX CHAR(1)
DEGREE NOT NULL VARCHAR2(10)

5、删除列和设置为不可用
语法解释
直接删除列:ALTER TABLE table_name DROP COLUMN column_name CASCATE CONTRAINTS
将列设置为不可用:ALTER TABLE table_name SET UNUSED COLUMN column_name CASCADE CONSTRAINTS
删除表内设置为不可用的列:ALTER TABLE table_name DROP UNUSED COLUMN

table_name:表名
column_name:列名
CASCATE CONTRAINTS:该参数不是必须的,如果删除的列是一个表的外键,也就是一个外键引用的父表,那么在删除时就需要使用此参数。
SET UNUSED:列不可用,数据字典里删除该列的定义(不可恢复)。如果同时设置多列为不可用 SET UNUSED (column_name1,column_name2)
DROP COLUMN:直接删除,多列同时删除 DROP (column_name1,column_name2)
DROP UNUSED COLUMNS:删除表内已经设置为不可用的列,只可以全部删除。

使用DROP删除列时,数据库会重新将该表的其他列写入磁盘,目的是为了还原需要,这样对于一个大表就会占用很大的undo空间,用来保存事务的整个RBS(rollback segment回滚段),这样做不仅容易造成报错ORA-01562(没有空间扩展回滚段)。而且容易造成由于undo空间不足造成数据库无法提供服务。
在对于一个较大的表进行删除时可以先将该列设置为不可用模式,然后在数据库负荷不大的时候再进行删除,并且删除每一定数据行创建一个检查点或commit一次,减少undo表空间的负担。

6、更改列的名字(重命名)
语法解释
ALTER TABLE table_name RENAME COLUMN old_column_name TO new_column_name

RENAME COLUMN:重命名列
old_column_name:原列名
new_column_name:新列名

十一、截断和删除表
TRUNCATE表有以下特点:
1、只删除表内数据不删除表结构
2、数据一旦删除就立即释放EXTENT占用的磁盘空间,并且数据不可恢复(extent保留为INITIAL_EXTENT大小)
3、如果该表被另一张表的外键引用,则无法使用TRUNCATE删除表中的数据
4、所有和表相关的索引也被截断
5、不会触发删除表的删除触发器

语法
TRUNCATE TABLE table_name;

DROP表有以下特点:
1、同时删除表结构和表数据
2、该表使用的extent立即得到释放,如果是连续的空间释放后会合并为一个FREE EXTENT空间
3、如果该表被另一个表的外键引用,则需要使用CASCADE CONSTRAINTS参数先将外键参考脱离。
4、对于还没有结束的事务,需要先将该表truncate才能drop

语法
DROP TABLE table_name CASCADE CONSTRAINTS


猜你喜欢

转载自blog.csdn.net/qqww120102/article/details/78054030