无论是数据库管理员,还是普通用户,都需要经常对数据库对象进行管理,如数据库对象的创建、删除、修改等。
Oracle 中的数据库对象包括表、索引、视图、存储程序、序列等,这些数据库对象以一种逻辑关系组织在一起,这就是模式( schema )。
模式是一个用户所拥有的所有数据库对象的集合。
每个数据库对象都属于某个用户,一个用户所拥有的数据库对象就组成了一个模式,模式的名称与用户名相同。
当创建用户时,就同时产生了一个模式,在默认的情况下,用户在自己的模式中有所有的权限。
将站在数据库管理员的角度,重新考虑这些数据库对象在Oracle 中所涉及的特性,如存储结构、数据的组织方式等。
表的管理
表的管理涉及表的结构、表的创建、修改与删除等操作,以及临时表、分区表和索引组织表三种特殊类型的表。
表的结构
在数据库中,表是最基本的数据库对象,用来存储系统或用户的数据。
表中的数据是按照行和列的格式存放的。
表中的各行数据一般以写入的先后顺序存放,而一行中的各列一般按照定义表时指定的顺序存放的。
在逻辑结构上,一个表位于某个表空间。
当创建一个表时,将同时创建一个表段,用于存放表中的数据。
在物理结构上,表中的数据都存放在数据块中,因而在数据块中存放的是一行行的数据。
图为数据块中一行数据的结构。
其中行的头部记录了该行中列的个数、行间的全连接、加锁信息等。
列长度记录-个列实际占用的字节数,而列值则记录了该列实际存放的数据。
表中的每一行数据都有一个行号,用于标识该行数据的物理位置。
根据这个行号,可以直接定位该行数据。
行号可以通过伪列ROWID获得。
例如,以下查询得到表DEPT中的数据及每行的行号。
SELECT rowid, emp.* FROM scott.emp;
行号是由数据库服务器自动生成的字符串,包含18个字符。
行号的组成如图所示。
其中前六个字符表示数据库对象的编号,用来指定该行数据属于哪个数据库对象。
在数据库中每个数据库对象都有一个唯一的编号。
从第七个到第九个共三个字符表示数据文件的相对编号,用来指定该行数据存储在哪个数据文件中。
在数据库中每个数据文件中有两个编号,一个是绝对编号,它是数据文件在整个数据库范围内的编号,另一个是相对编号,它是数据文件在一个表空间范围内的编号。
从第十到第十五共六个字符表示数据块的编号,用来指定该行数据位于哪个数据块中。
最后三个字符表示行号,用来指定该行数据在数据块中位于第几行。
为了使用户对行号的进行解析, Oracle提供了一个DBMS_ROWID程序包,利用这个程序包中的函数可以对行号进行分析。
DBMS_ROWID 中各个函数的用法如表所示。
例如,以下查询将得到dept表中每行数据所在的文件编号、数据库对象的编号、数据块编号和在数据块中的行号:
SELECT DBMS_ROWID.ROWID_RELATIVE_FNO(rowid) AS 相对文件号,
DBMS_ROWID.ROWID_OBJECT(rowid) AS 对象编号,
DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid) AS 数据块编号,
DBMS_ROWID.ROWID_ROW_NUMBER(rowid) AS 行号
FROM scott.dept;
表的创建
在创建表时,可以同时为表指定一些重要的属性,如存储参数、所属表空间等。
这些属性都通过CREATE TABLE命令的子句指定。
1.PCTFREE和PCTUSED子句
这两个参数的作用是用来控制数据块的空间使用情况。
为了减少数据块间的迁移,在创建表时可以通过PCTFREE和PCTUSED子句指定数据块空间的使用情况。
考虑以下创建表的语句:
CREATE TABLE Tl(
name varchar2 ( 10) )
PCTFREE 20
PCTUSED 40;
在表Tl 中,每个数据块都有20o/o的保留空间。
当可用空间使用完后,新的数据将被写入另外一个数据块。
当从表中删除数据时,数据块中已用空间不断减少,当减少到40%时,可再次向该数据块中插入数据。
在使用PCTFREE和PCTUSED子句时,可以参考以下原则:
• PCTFREE和PCTFUSED的值必须小于或等于100% 。
·如果在一个表上很少执行UPDATE操作,可以将PCTFREE设置得尽量小。
• PCTFREE与PCTUSED之和越接近100o/o ,数据块的空间利用率越高。
2.TABLESPACE子句
TABLESPACE子句用来指定将表创建在哪个表空间上。
如果不指定TABLESPACE子句,用户将在自己的默认表空间上创建表。
为了能够在指定的表空间上创建表,当前用户必须在该表空间上有足够的空间配额或在数据库中具有UNLIMITED TABLESPACE权限。
3.INITRANS和MAXTRANS子句
数据库中的数据存储在数据块中,用户的事务最终要修改数据块中的数据。
Oracle允许多个并发的事务同时修改一个数据块中的数据。
每当用户的事务开始作用于一个数据块时,数据库服务器将在该数据块的头部为该事务分配一个事务项,以记录事务的相关信息。
事务结束时,对应的事务项将被删除。
INITRANS和MAXTRANS参数用于控制一个数据块上的并发事务数量,其中INITRANS 用于指定初始的事务数量。
MAXTRANS 用于指定最大的并发事务数量。
当创建一个表时,数据库服务器按照INITRANS的值为每个数据块分配一定的事务项,这些事务项将一直保留到该表被删除。
当一个事务访问数据块时,将占用其中的一个事务项,事务结束时,将释放事务项。
当这些预先创建的事务项全部被占用后,如果又有新的并发事务发生,数据库服务器将在数据块的可用空间中为事务创建一个新的事务项。
在任一时刻,数据块中的事务项不会超过MAXTRANS 参数值。
例如,在利用以下语句创建表时,指定初始的事务项为10 ,最大的并发事务数量为2000
CREATE TABLE T2(
name varchar2 ( 10) )
INITRANS 10
MAXTRANS 200;
INITRANS和MAXTRANS参数的值可以根据用户对表的访问情况进行设置。
如果参数值过大,事务项将占用更多的数据块空间,那么数据可以利用的空间将喊少。
如果参数设置过小,有些事务将因为无法分配到事务项而等待,从而降低了数据库的性能。
一般情况下,如果多个用户同时访问表的情况很少发生,可以为这两个参数设置较小的参数值,反之要为这两个参数指定较大的参数值。
4.CACHE子句
CACHE子句用于指定将表中的数据放在数据库高速缓存中,并保留一段时间。
如果在创建表时指定了CACHE字句,那么在用户第一次访问表中的数据时,这个表将整个被读到数据库高速缓存中,并保留较长的一段时间,这样用户以后再访问该表时,可直接访问数据库高速缓存中的数据,从而提高访问的效率。
在默认情况下创建表时使用NOCACHE子句。
对于一些较小的、用户访问频繁的表,在创建时可以考虑使用CACHE子句,以提高访问效率。
CREATE TABLE T3(
name varchar2 ( 10) )
CACHE;
5.RAPALLEL子句
在一般情况下,通过INSERT命令向表中写人数据时,一次写入一行数据,这样的写操作是串行进行的。
如果在创建表时指定了PARALLEL子句,那么在向表中以批量方式写入大量数据时就是以并发方式进行的,这样可以大大提高处理的速度。
例如,利用以下语句创建表时,将实现并发操作。
CREATE TABLE T4(
name varchar2 ( 10) )
PARALLEL;
如果不希望在表上以并发方式写入数据,在创建表时需要指定NOPARALLEL 。
6.LOGGING子句
在默认情况下,用户在表上执行DDL和DML命令时,服务器进程都会产生重做日志。
如果不希望产生重做日志,在创建表时需要指定NOLOGGING子句。
使用NO LOGGING子句有以下好处:
·由于不写重做日志,因而节约了重做日志文件的存储空间。
.减少了处理时间。
·在以并行方式向表中写入大量数据时提高了效率。
当然在使用NOLOGGING子句时也有不好的一面。
因为没有重做日志,当表被破坏时,将无法进行恢复,所以在表创建后应该及时对其进行备份。
CREATE TABLE T5(
name varchar2 ( 10) )
NOLOGGING;
7.COMPRESS子句
如果在创建表时使用了COMPRESS子句,那么一个数据块中两行完全相同的数据将被压缩为一行,并存储在数据块的开始,在数据块中本应存储这两行数据的地方只存储该行数据的引用。
使用表的压缩功能可以减少表所占用的存储空间和数据库高速续存空间,并且可以提高查询速度。
表的压缩功能一般用在向表中批量插入数据的情况(例如基于查询创建表)。
一个表中可以包含压缩的和未压缩的数据,所有DML操作均可应用于这些压缩的数据。
例如,下面的语句用于创建表T6,这个表具有压缩功能,支持并发的数据写入,对DDL和DML命令不产生重做日志。
CREATE TABLE T6(
name varchar2 ( 10) )
COMPRESS PARALLEL NOLOGGING;
临时表是一种特殊类型的表,表中的数据并不永久保存,而是一些临时数据。
这些临时数据只在当前事务或当前会话中有效,当事务或会话结束时,这些临时数据将被全部删除。
创建临时表的命令是CREATE GLOBAL TEMPORARY TABLE 。
在创建临时表时还需要通过ON COMMIT子句指定临时数据的有效范围。
如果指定了ON COMMIT DELETE ROWS 子句,那么临时表是事务级的,当事务提交或回滚时,临时表中的数据即被删除。
如果指定了ONCOMMIT PRESERVE ROWS子句,那么临时表是会话级的,表中的数据将一直保留,直到当前会话结束时才被删除。
以下语句用于创建一个事务级的临时表:
CREATE GLOBAL TEMPORARY TABLE T7(
name varchar2(10)
ON COMMIT DELETE ROWS;