2009年2月12日星期四

数据字典data dictionary

数据字典是oracle数据库的一个重要组成部分,这是一组用于记录数据库信息的表(这个表是read-only的)。数据字典中包含:
数据库中所有方案对象(schema object)的定义(包括表table、视图view、索引index、簇index、同义词synonyms、序列sequence、过程procedure、函数function、包package、触发器trigger等等)

数据库为一个方案对象分配了多少空间,以及该对象当前使用了多少空间。
列的默认值
完整性约束(integrity constraint)信息
数据库用户名
每个用户被授予(grant)的权限(privilege)与角色(role)
监控(audit)信息,例如那个用户对某个方案对象进行了访问或更新操作
数据库中的其何使用数据字典
数据字典有三个主要用途:
oracle利用数据字典来获取关于用户、方案对象、及存储结构(storage structure)的信息
每当数据库中执行了DDL语句后,oracle将对数据字典进行修改
所有oracle用户都可以使用数据字典来获取关于数据库的信息
一、oracle如何使用数据字典
数据字典基表中的数据是oracle正常工作所必须的。因此,只有oracle才能增加或修改数据字典中的信息。当用户对数据库进行升级(upgrade)或降级(downgrade)的操作时,oracle提供了修改数据字典的脚本。
注:任何用户都不应该删除或修改数据字典表内的数据
在数据库运行期间,oracle通过数据字典内的信息来确定方案对象(schema object)是否存在,以及用户是否具备相应的权限。oracle会持续地更新数据字典,以便反映在数据库结构、监控、授权和数据等方面的变化。
例如:当用户创建了名为parts的表,则数据字典中将会增加记录这个新表,及相关列,数据段(segment),数据扩展(extent)的数据,并记录用户对此表的权限(privilege)信息。当数据字典再次被查询时,用户就能够看到这些信息。
二、如何使用数据字典how to use the data dictionary
所有数据库用户都可以参考数据字典视图提供的信息。用户可以使用SQL语句来访问数据字典视图。有些视图可以供所有oracle用户使用,而有些只有DBA才能访问。
只要数据库处于打开(open)状态,用户就可以使用数据字典。因为数据字典存储在SYSTEM表空间内,此表空间在数据库被打开后总是联机(online)的。
数据字典视图可以被分为多组。大多数情况下,一组视图由三个包含相似信息的视图构成,其中的区别在于视图名称的前缀:
前缀是USER,表明是用户视图(用户方案(schema)内的对象)
前缀是ALL,扩展的用户视图(用户可访问的对象)
前缀是DBA,DBA视图(所有用户方案内的对象)
同一组中各视图所包含的列是完全相同的,但有以下除外:
使用USER前缀的视图通常没有OWNER列。对于USER视图来说,这列的值等于提交查询的用户名
有些以DBA为前缀的视图包含管理员所需的额外列
二、动态性能表dynamic performance table
在数据库运行过程中,oracle将维护一组虚拟表(virtual table)用于记录数据库的当前状态(current database activity)。这组表被称为动态性能表(dynamic performance table)。
动态性能表并不是真正的表,大多数用户不应访问其中的信息,但是数据库管理员可以对其进行查询,或在其上创建视图并将访问权限授予其他用户。这些视图有时被称为固定视图(fixed view),因为数据库管理员不能将其修改或移除。
动态性能表由SYS用户所拥有,他们的名字都是以V_$开头。这些表上创建有视图,而视图上创建有公共同义词。这些同义词的名字都是以V$开头,例如,V$DATAFILE视图包含了数据库文件的信息,V$FIXED_TABLE视图包含了数据库所有动态性能表及视图的信息。
三、数据库对象元数据database object metadata
DBMS_METADATA包为用户提供了获取数据库对象完整定义的接口。此包可以通过XML或SQL DDL的形式提供定义信息。此包具备两类接口:
1、用于进行编程的灵活且完善的接口(A flexible,sophisticated interface for programmatic control)
2、用于随机查询(ad hoc querying)的简化接口
他概要信息
与数据库内的其他数据相同,数据字典也是以表及视图的形式组织的。一个数据库全部的数据字典表与数据字典视图都存储在该数据库的SYSTEM表空间内。
数据字典不仅是oracle数据库的基础组成部分,它也为所有用户--从终端用户,到应用程序设计者,再到数据库管理员--提供了一个重要的工具。数据字典可以通过SQL语句进行访问。由于数据字典是只读的,用户只能对这些表和视图执行查询操作(select语句)。
数据字典由以下两种结构组成:
1、基表
基表(base table)用于存储相关的数据库信息。只有oracle才能读这些表。用户很少直接访问它们,因为这些表是规范化的(normalized),且其中的大部分数据的含义是普通用户无法理解的。
2、用户访问视图user-accessible views
用户访问视图(user-accessible view)用于对数据字典基表内存储的数据进行汇总与展示。这些视图利用连接(join)及WHERE子句简化基表中的数据,将其解码(decode)为用户可理解的信息,例如用户名、表名等。大多数用户只能访问这些视图,而不能访问基表。
oracle中的SYS用户拥有数据字典中的所有基表(base table)及用户访问视图(user-accessible view)。其他oracle用户不应修改(UPDATE、DELETE或INSERT)SYS方案中的对象定义以及数据,否则将危害数据库的数据完整性(data integrity)。安全管理员必须严格控制此帐户。
注:修改或操作数据字典表中的数据可能会给数据库的运行带来不可恢复的损害。

依赖性 dependencies among schema objects

某些类型的方案对象可以在其定义中引用其他对象。例如:视图的定义就是一个引用了其他表或视图的查询;一个过程中也可以包含引用了其他数据库对象的SQL语句。如果一个对象的定义中引用了其他对象,那么这个对象被称为依赖对象(dependent object),此对象所引用的对象被称为被引用对象(referenced object)。
如果用户修改(alter)了一个被引用对象(referenced object)的定义,则相应的依赖对象(dependent object)是否能够正常工作将取决于修改该的类型。例如:如果用户移除(drop)了一个表,那么所有基于此表的视图将失效。
oracle能够自动地记录对象间的依赖关系,以便降低依赖性管理的复杂程度,减轻数据库管理员和用户的工作负担。例如,一个表被多个过程所引用,当用户修改了被引用表(referenced table)的定义后,oracle将在依赖过程(dependent procedure)下一次被引用时自动地将其重新编译(recompile)。
为了管理方案对象间的依赖关系,oracle需要记录所有的方案的状态(status):
有效的(valid)已经通过编辑,可以在被引用时直接使用
无效的(invalid)必须在使用之间进行编译。对于过程(procedure)、函数(function)、包(package)来说,这意味着对其进行编译。对于视图来说,这意味着此视图必须使用被引用对象(referenced object)当前在数据字典中的定义信息(current definition)重新进行语法分析。
只有依赖对象(dependent object)可以处于无效(invalid)状态。表(table)、序列(sequences)和同义词(synonyms)总是处于有效状态(valid)。
如果一个视图(view)、过程(procedure)、函数(function)或包(package)处于无效状态,oracle会尝试对其进行重新编译,但是这个过程可能会发生错误。例如,当编译一个视图时,此视图的基表(base table)有可能不存在,或访问基表的权限不存在;当编译一个包时,有可能出现PL/SQL或SQL语法错误、或访问被引用对象(referenced object)的权限不存在。在编译时发生此类问题的方案对象(schema object)将保持无效状态。
oracle能够自动地跟踪数据库中发生的特定变化,并在数据字典中记录相关的方案对象的最新状态。
状态记录时一个递归过程。被引用对象(referenced object)的状态变化不仅对导致其直接依赖对象(directly dependent object)的状态变化,同时会影响其间接依赖对象(indirectly dependent object)的状态。
例如:当一个存储过程引用了一个视图的时候,这个存储过程间接的引用了此视图的基表。
一、解析方案对象的依赖性(resolution of schema object dependencies)
当一个方案对象(schema objcet)在SQL语句中被直接引用或被此语句中的依赖对象(dependent object)所引用(或间接引用)时,oracle均会在需要时对其状态进行检查。SQL语句中被直接或间接引用的对象的状态决定了oracle的后续操作。
如果SQL语句中所有的被引用对象(referenced object)均处于有效状态,则oracle无需进行其他工作就可以直接执行SQL语句。
如果SQL语句中引用的任何视图、PL/SQL程序结构(过程procedure、函数function、包package),oracle将自动地尝试编译这些对象。如果所有的无效的被引用对象(referenced object)都能被成功编译,则oracle将在编译后执行SQL语句。如果一个方案对象不能被成功编译,那么它将继续保持无效状态。oracle回滚执行失败的SQL语句并返回一个错误信息。事务(transaction)中已经成功的操作由用户决定是进行提交还是回滚。
如果一个方案对象在处于无效状态之后被用户替换(replace)掉,则oracle不会对其进行重新编译。这项优化错误减少了不必要的重新编译操作。
1、编译视图及PL/SQL程序结构
当满足以下条件时,视图及PL/SQL程序结构可以被编译并置为有效状态:
视图或PL/SQL程序结构的定义必须正确。SQLj及PL/SQL语句的语法结构必须正确。
所有被引用对象(referenced object)及其结构必须满足定义的要求。例如:如果视图的定义查询(defining query)中引用了某列,那么此列必须存在于基表(base table)中。
视图或PL/SQL程序结构的所有者必须具备访问引用对象的权限。例如:过程中的一个SQL语句向某个表中插入一条数据,那么此过程的所有者必须具备对被引用表(referenced table)的INSERT权限。
注:如果一个视图所引用的基表或其他视图被修改(alter)、重命名(rename)或移除(drop)后,此视图将被置为无效状态,但是这个视图的定义仍被保存于数据字典内,相关的权限信息,引用此视图的同义词(synonyms)、对象,及其他视图也都会被保留(虽然视图处于无效状态,但是这个视图的定义还是存在的)。
当用户需要使用一个处于无效状态的视图时,oracle会在运行时自动重新编译此视图。而当一个视图被替换(replace)后,其有效性由以下条件决定:
视图的定义查询中所引用的全部基表(base table)必须存在。如果视图所引用的一个基表被重命名(rename)或被移除(drop),视图将被置为无效状态且不可用。引用无效视图的语句将会失败。只有当基表恢复原名或重建视图才能被成功编译。
如果基表被修改或重建(re-created)后保留了原来的全部列,但是某些列的数据类型发生了变化,那么大部分依赖视图能够被成功地重新编译。
如果视图的基表被修改或重建后保留了原来的全部列,那么此视图的状态仍为有效。如果重建的基表中不再包含视图所引用的列,那么此视图的状态将被置为无效。如果视图时使用SELECT * FROM table形式的语句定义的,常会导致上述情况中的后者出现,因为在视图创建时其定义查询(defining query)将被扩展到基表的所有字段并永久存储于数据字典中。
二、解析方案对象名称
在SQL语句中引用的方案对象名称可由多段(piece)组成,各段之间使用“.”分隔。以下内容描述了oracle如何就解析对象名称:
1、oracle首先验证SQL语句中所引用的对象名称的首段。例如在hr.employees中,hr位首段。如果引用的名称只由一段构成,则此段就被看作时首段。
a、oracle首先在当前方案中搜索名称与对象名首段相符的对象。如果不存在则进入到步骤b。
b、oracle搜索名称与对象名称首段相符的公有同义词(public synonym)。如果不存在,则进入到步骤c。
c、oracle搜索名称与对象名称首段相符的方案,如果找到这样一个方案,则返回步骤b,使用对象名称的第二段在方案中搜索相符的对象。如果方案中不存在相符的对象,或引用的对象名称只由一段构成,则oracle将返回一个错误。
注:如果在步骤c中没有找到相符的方案,那么引用的对象名称也不能被验证,oracle将返回一个错误。
2、如果数据中存在语句中所引用的方案对象,这个方案对象还必须具备对象名称剩余段所代表的内容。例如:当引用名称为hr.employees.department_id时,如果hr代表方案名称,employees代表表名,那么department_id必须与employees表中的某个列名称相符;如果employees代表包名称,那么包内必须存在名为department_id的公有常量、变量、过程或函数。
三、共享SQL的依赖性管理
oracle 除了需要管理方案对象的依赖性,还需要管理共享池(shared pool)中各个共享SQL区(shared SQL area)的依赖性。如果用户创建、修改或移除了表、索引、同义词或序列,或者重新编译了包、或包声明,那么所有依赖共享SQL区都将被置为无效。当一个基于无效共享SQL区的游标继续执行时,oracle将重新对SQL语句进行语法分析,并生成新的共享SQL区。
四、本地及远程依赖性管理
监控数据库内的依赖性以及进行必要的重编译都是由oracle自动地执行的。本地依赖性管理(local dependency management)是指oracle管理一个单一数据库内各个对象间的依赖关系。例如:某过程内的一个SQL语句引用了相同数据库中的一个数据表。
远程依赖性管理(remote dependency management)是指oracle管理一个分布式环境内的各种依赖关系。例如:一个oracle forms触发器可以依赖于一个数据库内的方案对象;在一个分布式数据库内,一个本地视图的定义查询可以引用一个远程表。
1、本地依赖性管理
oracle使用数据库内部的依赖性关系表(dependency table)来管理所有的本地依赖性,依赖关系表用于记录每个方案对象的依赖对象(dependent object)。当用户修改了一个被引用对象(referenced object),oracle就会使用依赖关系表确定此对象的所有依赖对象,并将它们全部置为无效状态。
例如:假设存储过程UPDATE_SAL引用了JWARD.employees表。当JWARD.employees表的定义被修改后,所有引用此表的对象都将被置为INVALID,包括存储过程UPDATE_SAL。此存储过程必须经过重新编译并置为有效状态后才能再次运行。同样,当一个用户所拥有的对象权限(DML privilege)被撤销(revoke)后,此用户方案内的所有依赖对象也将被置为无效状态。但在后面这种情况中,由于使对象无效的原因使授权(authorization)被撤销,因此可以通过重新授权(reauthorization)使对象恢复有效状态,此时无需对无效对象进行重新编译操作。
2、远程依赖性管理
oracle还要管理应用程序与数据库间的依赖关系,以及分布式数据库间的依赖关系。例如:oracle forms应用程序可以使用一个引用了数据表的触发器;本地的存储过程也可能调用分布式数据库系统中的远程过程。数据库系统必须能够管理此类对象间的依赖关系。oracle根据对象的不同而选择不同的机制来管理远程依赖性。

2009年2月8日星期日

方案对象schema object

方案是一个逻辑数据(logical structures of data)(或称为方案对象(schema object))的集合。每个数据库用户拥有一个与数据库用户同名的方案,且只有这一个方案。方案对象可以通过SQL语句创建和操作。方案对象包含以下对象类型:
簇(cluster)
数据库链接(database link)
数据库触发器(database trigger)
维度(dimension)
外部过程库(external procedure library)
索引(index)和索引类型(index type)
Java类(Java class),Java资源(Java resource),及Java源程序(Java source)
物化视图(materialized view)及物化视图日志(materialized view log)
对象表(object table),对象类型(object type),及对象视图(object view)
操作符(operator)
序列(sequence)
存储(在服务器端)的(stored)函数(function),过程(procedure)及包(package)
同义词(synonym)
表及index-organized table
视图(view)
还有一些类型的对象也存储于数据库中,且可由SQL语句创建或操作,但是他们不属于任何方案(schema):contexts、目录(directory)、用户配置(profile)、角色(roles)、表空间、用户(user)
方案对象(schema object)是一种逻辑数据存储结构(logical data storage structure)。oracle在逻辑上将方案对象存储于数据库的表空间,而方案对象的数据在物理上存储于此表空间的一个或多个数据文件中。因此方案对象不一定与磁盘上存储这些方案对象的数据的物理文件(physical file)一一对应(即可能两个对象的数据存储在一个物理文件中)。用户可以对表、索引、及簇等对象的磁盘空间分配进行设定。
方案(schema)与表空间之间没有必然联系。同一个表空间可以包含不同方案的对象,而同一方案的对象也可以存储在不同表空间中。
一、表概述
表(table)是oracle数据库中最基本的数据存储结构。数据在表中以行(row)和列(column)的形式存储。用户在定义表时,需要设定表名,还需要设定表内各列的列名(column name)、数据类型(datatype)、及宽度(width)。有些数据类型的宽度是固定的,例如DATE类型,而对于NUMBER类型的列来说,则需要定义精度(precision)及数值范围(scale)。数据行是一条记录(single record)各列信息的集合。
用户可以为一个表的各列数据的值设定规则。这些规则被称为完整性约束(integrity constraint)。例如NOT NULL完整性约束,它要求各行的此列必须包含值。
用户可以设定表内某些列的数据在存储到数据文件之前首先进行加密(encryption)。加密可以防止未经授权的用户绕过数据库访问控制机制,使用操作系统工具直接查看数据文件的内容。
在用户创建(create)表后,就可以使用SQL语句向其中插入(insert)数据,或使用SQL语句查询(query),删除(delete),或更新(update)表内的数据。
二、视图概述
视图(view)用于展现整理后(tailored)的一个或多个表或其他视图中的数据。视图将一个查询的结果作为一个表来使用。因此视图可以被看到是存储查询(stored query)或一个虚拟表(virtual table)。大多数情况下,只要能够使用表就能使用视图来实现。
例如:如果管理员希望用户只能查询其中的5列及特定的数据行,就可以创建此表的视图供用户访问。
由于视图来源于表,因此两者有许多相似之处。例如,用户定义的视图和表一样,最多包含1000列。用户可以查询(query)视图,遵从某些限制(restriction)时还可以对视图进行更新(update)、插入(insert)、删除(delete)等操作。所有对视图数据的修改最终都会被反映到视图的基表(base table)中,这些修改必须服从基表的完整性约束(integrity constraint),并同样会触发定义在基表上的触发器(trigger)。
用户即可以在视图上显式地定义触发器(trigger),也可以在视图所引用的基表上定义触发器。oracle还支持在视图上定义逻辑约束(logical constraint)。
三、索引概述
索引是数据库中一种可选的数据结构,它通常与表或簇相关。用户可以在表的一列或数列上建立索引,以提高在此表上执行SQL语句的性能。oracle的索引提供了更为迅速地访问表数据的方式。正确地使用索引能够显著的减少磁盘的I/O。
用户可以为一个表创建多个索引,只要不同索引使用的列或列的组合(combination of columns)不同即可。

事务

事务是由一个或多个SQL语句组成的逻辑操作单位(logical unit of work)。事务具有原子性(atomic)。一个事务内所有SQL语句对数据库产生的影响,要么全部被提交(commit)(作用到数据库中),要么全部回滚(roll back)(将对数据库的修改撤销)。
一个事务开始于用户提交第一条可执行(executable)的SQL语句,结束于之后进行的提交(commit)或回滚操作。使用COMMIT或ROLLBACK语句能够显式地(explicitly)结束事务,而提交一个DDL语句可以隐式地(implicitly)结束事务。
如果发生问题,导致事务中的一条或两条SQL语句不能执行,那么整个事务必须回滚,这样才能保证完整性。
1、语句的执行与事务控制(statement execution and transaction control)
一个成功执行的SQL语句与一个提交的事务是有区别的。一个SQL语句成功执行表明此语句:解析正常、是有效的SQL语法结构、作为一个独立的语句运行无误(例如:在一个多行更新(multirow update)操作中所有数据行都被成功修改)。
但是包含此语句的事务被提交之前,整个事务都可以被回滚,事务内所有语句对数据库的修改都可以被撤销。尽管发生了回滚,事务内的SQL语句却是成功执行的。
提交(commit)意味着用户显示地(explicitly)或隐式地(implicitly)要求将事务中对数据的修改永久地记录到数据库当中。当用户执行COMMIT语句时即为显式的提高叫操作,当数据库应用程序正常结束或一个数据定义语句(data definition language)成功执行后将发生隐式的提交操作。事务被提交后,事务内SQL语句的对数据的修改将被永久地记录到数据库中,其他用户将能够看到这些改变。在事务提交后执行的查询就能看到变化后的数据了。
用户可以在开始一个事务时,使用SET TRANSACTION ... NAME语句为此事务命名。这有助于用户监控长时间运行的事务,以及处理不可信的分布式事务(in-doubt distributed transaction)。
2、语句级回滚statement-level rollback
如果在一个SQL语句在执行过程中发生了错误,那么此语句对数据库产生的影响都将被回滚。回滚后就如同此语句从未执行过,这种操作被称为语句级回滚。
在语句执行过程中,任何发生的错误都将会导致语句级回滚,例如同一个表中插入数据造成主键(primary key)值重复即为此类错误。一个造成死锁(deadlock)(访问相同数据而产生的竞争)的SQL语句也会导致语句级回滚。而在SQL语句解析(parsing)的过程中发生的错误(例如语法错误),因为此语句还没有执行,所以不会产生语句级回滚。
一个SQL语句执行失败只会使此语句所做的数据修改无效,而不会导致当前事务中此语句之前的语句所做的数据修改无效。如果执行失败的是DDL语句那么此语句之前隐式执行提交操作不会被撤销。
3、可恢复的空间分配问题
当一个持续时间较长的数据库操作在执行过程中遭遇空间分配失败时,oracle可以将此操作暂时性挂起(suspend),并在空间分配问题解决后恢复(resume)其执行。当发生空间分配问题时,oracle数据库不会立即 给执行此操作的用户返回错误提示,而是等待管理员解决此问题。当空间分配问题被纠正后,挂起的操作就可以自动地恢复执行。
注:只有在客户端使用ALTER SESSION语句的语法显式地将会话设定为可恢复(resumable)后,SQL语句才能运行在可恢复模式下(resumable mode)。
当满足以下条件时,运行于可恢复的空间分配模式下的语句将被挂起(suspend):无可用空间、达到最大的数据扩展(maximum extent)限制、超出空间配额(space quota)限制
在不可恢复的空间分配模式下,以上条件将导致运行错误,并使SQL语句回滚。
当语句被挂起将导致所在事务同时被挂起。事务所使用的所有资源在语句挂起期间都将被保留。
当产生错误的条件消除后(例如,管理员进行了处理,或其他查询使用的排序空间(sort space)被释放),被挂起的语句将自动地恢复执行。