ORACLE数据库技术实用详解
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.1 数据字典表

数据字典是整个Oracle数据库的核心,它描述了数据库自身的信息(比如数据文件在哪里等)以及数据库里记录对象的信息。它由两部分组成:数据字典基本表和数据字典视图。

数据字典基本表与普通用户创建的表没什么区别,只不过其中存放了数据字典的数据。这些表是在创建数据库时,由create database命令创建的。更确切地说,是通过create database命令调用sql.bsq文件而创建的。该文件位于$ORACLE_HOME/rdbms/admin目录下。打开该文件,我们可以发现,数据字典基本表几乎都是以$结尾,比如col$、tab$等。

这些数据字典基本表的所有者是用户sys,也就是Oracle数据库的超级用户。这些数据字典物理地存放在system表空间里。用户只能读取数据字典表,而不能用DML语句去修改这些数据字典表。尽管它们与普通表一样,也是可以被DML语句修改的,但我们绝对不应该去修改它们。因为一方面,数据字典基本表里的数据含义很隐讳,也没有文档记录其中包含数据的含义;另一方面,数据字典基本表之间有着错综复杂的关系,我们修改了一个表,会导致该表与其他表的信息不一致,从而导致整个数据库崩溃。一旦数据字典基本表的数据发生损坏,则数据库就必须从备份中进行恢复了。

由于基本表之间的关系过于复杂,同时数据含义难懂,不便于查询。因此,Oracle还提供了数据字典视图来简化数据字典。这些视图隐藏了基本表之间的复杂关系,并为隐讳的列名提供了含义清楚的列名,使得我们从视图的列名就能知道该列的含义。

这些数据字典视图的所有者也是用户sys,为了方便其他用户访问这些视图,Oracle还为所有的数据字典视图创建了公共的(public)同名词(synonym),所谓同名词就是别名。这样,数据库里的任何用户都通过别名来访问有权查看的视图了。这些数据字典视图以及同名词通过脚本catalog.sql创建。

注 意 在创建数据库时,有两个脚本是一定要运行的。先要运行catalog.sql,该脚本用来创建数据库的内部字典表。然后再运行catproc.sql,该脚本用来创建数据库的内建的存储过程、包等PL/SQL对象。如果我们是使用dbca来创建数据库的,则dbca会自动调用这两个脚本。否则,如果我们直接通过create database命令来创建,则需要手工运行这两个脚本。

数据字典视图分为三个层面:DBA、ALL以及USER。所谓DBA层面,表示以DBA_开头的视图,其中包含了整个数据库范围的数据。比如dba_tables视图就包含了数据库里所有表的信息。用户需要一定的授权才能访问DBA层面的视图;ALL层面表示以ALL_开头的视图,其中包含了当前登录用户有权限看到的数据。它是DBA_视图的子集。比如all_tables记录了当前登录用户有权访问的所有表的信息;USER层面表示以USER_开头的视图,其中包含了当前登录用户所拥有的所有表的信息。它是ALL_视图的子集。

数据字典视图非常多,比如dba_tables里记录了所有表的信息,dba_tab_columns则存放了所有表的所有列的信息等。我们不需要一一都记住,但是有一个视图,我们必须知道,那就是dictionary视图。因为该视图里记录了所有的数据字典视图的名称。所以当我们需要查找某个数据字典信息而又不知道这个信息记录在哪个视图里的时候,就可以到dictionary视图里找。该视图还有个同名词:dict。

    SQL> desc dictionary
    Name              Null?      Type
    --------------- -------- ----------------
    TABLE_NAME                   VARCHAR2(30)
    COMMENTS                     VARCHAR2(4000)

可以看出,dictionary视图有两个列:TABLE_NAME表示视图名称,它是大写的。COMMENTS表示注释,是小写的。比如,我们想知道存放同名词的视图是哪个,则:

    SQL> select table_name from dict where table_name like '%SYNONYM%';
    TABLE_NAME
    ------------------------------
    DBA_SYNONYMS
    USER_SYNONYMS
    ALL_SYNONYMS

于是我们可以到dba_synonyms里验证一下,dba_tables是否为为同名词。

    SQL> select owner,synonym_name,table_owner,table_name
      2  from dba_synonyms where synonym_name='DBA_TABLES';
    OWNER       SYNONYM_NAME   TABLE_OWNER   TABLE_NAME
    -------  ------------- ----------- -----------
    PUBLIC      DBA_TABLES      SYS            DBA_TABLES

可以很明显看到,dba_tables确实是一个同名词,指向用户sys下的dba_tables。那么dba_tables到底是一个什么类型的对象呢?我们可以在dba_objects视图里进行查找,该视图记录了数据库中的所有对象。

    SQL> select owner,object_name,object_type from dba_objects where object_name='DBA_TABLES';
    OWNER            OBJECT_NAME              OBJECT_TYPE
    ------         ------------           -------------
    SYS              DBA_TABLES               VIEW
    PUBLIC           DBA_TABLES               SYNONYM

可以看到,名为dba_tables的对象有两种,一种是我们见过的同名词,另一种就是视图。于是我们继续追踪,到dba_views视图(该视图记录了数据库中所有视图的定义信息)里查找dba_tables的定义方式。

    SQL> set long 1000000000
    SQL> set pages 999
    SQL> select text from dba_views where view_name='DBA_TABLES';
    TEXT
    --------------------------------------------------------------------------------
    select u.name, o.name, decode(bitand(t.property,2151678048), 0, ts.name, null),
          decode(bitand(t.property, 1024), 0, null, co.name),
    ……
    from sys.user$ u, sys.ts$ ts, sys.seg$ s, sys.obj$ co, sys.tab$ t, sys.obj$ o,
        sys.obj$ cx, sys.user$ cu, x$ksppcv ksppcv, x$ksppi ksppi
    where o.owner# = u.user#
    ……

到这里,我们就验证了前面说到的有关Oracle里数据字典视图的组织方式。它是先基于数据字典基本表创建视图,然后为视图创建一个同名的同名词,并将该同名词赋给了PUBLIC,从而使得所有用户都可以通过同名词查看数据字典的信息。

在本书中,我们不会对每个数据库功能所涉及的数据字典进行描述和说明。如果需要查看相关的数据字典,请参照这里所描述的方法,到dict里查找所需要的数据字典信息。