不能通过任何SQL语句来设置标准的ROWID伪列的值。
列或变量可以定义成ROWID数据类型,但是Oracle不能保证该列或变量的值是一个有效的ROWID。
LOB
LOB(大型对象)数据类型,可以保存4GB的信息。LOB有以下3种类型:
·CLOB,只能存储字符数据
·NCLOB,保存本地语言字符集数据
·BLOB,以二进制信息保存数据
可以指定将一个LOB数据保存在Oracle数据库内,还是指向一个包含次数据的外部文件。
LOB可以参与事务。管理LOB中的数据必须通过DBMS_LOB PL/SQL内置软件包或者OCI接口。
为了便于将LONG数据类型转换成LOB,Oracle9i包含许多同时支持LOB和LONG的函数,还包括一个ALTER TABLE语句的的新选择,它允许将LONG数据类型自动转换成LOB。
BFILE
BFILE数据类型用做指向存储在Oracle数据库以外的文件的指针。
XMLType
作为对XML支持的一部分,Oracle9i包含了一个新的数据类型XMLType。定义为XMLType的列将存储一个在字符LOB列中的XML文档。有许多内置的功能可以使你从文当中抽取单个节点,还可以在XMLType文档中对任何节点创建索引。
用户自定义数据
从Oracle8以后,用户可以定义自己的复杂数据类型,它们由Oracle基本数据类型组合而成。
AnyType、AnyData和AnyDataSet
Oracle包括3个新的数据类型,用于定义在现有数据类型之外的数据结构。其中每种数据类型必须用程序单元来定义,以便让Oracle9i知道如何处理这些类型的特定实现。
类型转换
Oracle会自动将某些数据类型转换成其他的数据类型,转换取决于包括该值的SQL语句。
数据转换还可以通过Oracle的类型转换函数显示地进行。
连接与比较
在大多数平台上Oracle SQL中的连接操作符用两条竖线(||)表示。连接是将两个字符值连接。Oracle的自动类型转换功能使得两个数字值也可以进行连接。
NULL
NULL值是关系数据库的重要特征之一。实际上,NULL不代表任何值,它表示没有值。如果要创建表的一个列,而这个列必须有值,那么应将它指定为NOT NULL,这表示该列不能包含NULL值。
任何数据类型都可以赋予NULL值。NULL值引入了SQL运算的三态逻辑。如果比较的一方是NULL值,那么会出现3种状态:TURE、FALSE以及两者都不是。
因为NULL值不等于0或其他任何值,所以测试某个数据是否为NULL值只能通过关系运算符IS NULL来进行。
NULL值特别适合以下情况:当一个列还未赋值时。如果选择不使用NULL值,那么必须对行的所有列都要赋值。这实际上也取消了某列不需要值的可能性,同时对它赋的值也很容易产生误解。这种情况则可能误导终端用户,并且导致累计操作的错误结果。
基本数据结构
表
表是关系数据库中的一个基本数据结构。表就是行的集合。每行(row)包含一个或多个列。
从Oracle8企业版以后,就提供了分区选件,它允许将表和索引进行分区。利用分区,Oracle可从以下两方面改善性能:
·Oracle不用去访问那些不满足查询条件的分区
·如果分区中所有数据都满足查询条件,那么Oracle将选择全部数据而不需要对每行均进行字句检查。
视图
视图(view)是Oracle中的一种由SQL语句构造的数据结构。SQL语句存储在数据库中,在查询中使用一个视图时,所存储的查询将得以执行,并向用户返回基表(base table)中的数据。
视图不包含数据,而是表示一些方法可以查看查询所指定的基表数据。
视图有以下几种用途:
·简化对多个表数据的访问
·可以保证表中数据的安全(如,创建包含WHERE子句的视图就可以限制访问表中的数据)
·将应用与表中某些特定的结构分离
视图建立在基表集合的基础之上,基表包括Oracle数据库中的事实表或者其他视图。如果视图中的任何一个基表进行修改,那么该视图将无法继续使用它们,因此视图本身也无法再使用。
索引
索引(index)是用来加快访问数据库中记录速度的一种数据结构。一个索引与一个特定的表相关,而且包含该表的一个或多个列的数据。
创建索引的SQL基本语法:
CREAT INDEX emp_idx1 on emp (ename,job);
其中,emp_idx1时索引名,emp是创建索引的表,ename和job时构成索引的列值。
除了索引数据以外,索引项中还为其相关行保存了ROWID。ROWID是获取数据库行的最快方式,因此随后数据库行的获取都是以这种最佳方式来完成。
Oracle中使用的4中类型的索引结构:标准B*-树索引、反向键索引、位图索引以及Oracle8i引入的基于函数的索引。Oracle使你可以对表中的数据进行聚合,从而改善性能。
其它数据结构
序列(Sequence)
在多用户数据库中经常出现的大问题,就是很难为键或标识符提供唯一的序号。在这种情况下,Oracle允许创建序列对象。
序列号可以用名字,一个递增值或有关序列的其他一些信息。序列独立于任何表,因此多个表可以使用同样的序列号。
同义词(Synonym)
所有的Oracle数据库的数据结构都存储在一个特定的模式(schema)。模式是和一个特定的用户名相关联的,所有对象都通过带有对象名的模式名得到引用。
例如,模式DEMO中有一个表名为EMP。如果想引用表EMP,那么应该通过完整名DEMO.EMP来引用。如果没有提供特定的模式名,那么Oracle假定该结构处于当前用户名的模式中。
集群(Cluster)
集群是一种能够改善获取性能的数据结构。集群和索引一样,不会影响表的逻辑视图。
散列集群(Hash Cluster)
数据设计
约束
约束(constraint)强制数据库中某些数据的完整性。当给某列增加一个约束,Oracle自动确保不满足此约束的数据是绝不能被接受的。
约束可以在创建或增加包括某列(通过关键字)的表时与列相关联,或者在表创建后通过SQL命令ALTER TABLE来实现与该列的关联。在Oracle8及以后的版本中支持以下5个约束类型:
NOT NULL
对于任何列都可以设为NOT NULL。如果在任何SQL操作中将一个NULL值赋给某个有NOT NULL约束的列,Oracle会为这个语句返回一个错误。
惟一性
主键
外键
校验
某些约束需要创建所以来支持。
约束可以是立即的或延迟的。立即约束(immediate constraint)只要有写操作就会立即对受约束列产生影响;而延迟约束(deferred constraint)只有在对约束行产生变化的SQL语句执行完时才有强制作用。
对于某个特定表的约束可设置成暂时挂起。当再次启动该约束操作时,再要求Oracle对该约束验证所有数据,或者只是对新数据应用约束。在现有表中增加约束时,可以指定是否对表中所有记录进行约束校验。
触发器
触发器是个代码块,当某个表中发生了某种类型的数据库事件时它就会被触发,有以下3种事件会导致触发器的触发:
·数据库UPDATE
·数据库INSERT
·数据库DELETE
例如,可以定义一个触发器,从而在用户改变某一行时,写一个定制的审查记录。
触发器是在行一级被定义的。可以指定触发器是对每一行触发,或者对触发该触发器事件的SQL语句触发。
触发器的触发有3个时机: ·在执行触发事件之前 ·在执行触发事件之后 ·非触发事件
将前两种时间选项与触发器所触发的行和语句的结合,则有4种可能的触发器实现:在语句之前;在行之前;在语句之后;在行之后。
任何触发器都可以有一个触发器限制(trigger restriction)。触发器限制是一个布尔表达式,如果其值为FALSE,那么就阻止触发器触发。
触发器的定义和存储都独立于使用它们的表。因为触发器包含逻辑,所以必须通过比SQL功能强的某种实现数据访问的语言来写。可以直接用PL/SQL或Java来写触发器,也可以通过调用其中任一种语言编写的现有存储过程来写触发器。
触发器触发是SQL语句执行的结果,该SQL语句修改了某个表中的行。触发触发器的操作可能是修改这个表中的数据,或者产生某些改变来触发其他表的触发器。这么做的最后结果可能是以某种方法修改了数据,但Oracle认为这是不合逻辑的。这些情况都会导致Oracle返回变异表(mutating table,被其他触发器修改的表)的运行时错误,或是返回约束表(constraining table,被其他约束修改的表)的运行时错误。
Oracle8i还引入了一组非常有用的系统事件触发器和用户事件触发器。现在可以在系统事件(如,数据库启动或关闭)中放置触发器,也可以在用户事件(登录和退出)中放置触发器。
查询优化
不用事先定义访问数据的路径是关系数据库的一大优点。向Oracle数据库提交一个SQL查询时,Oracle必须确定如何访问数据。因为Oracle要找到一种最佳的方式来检索数据,所以进行决策的过程称为查询优化(query optimization)。这种检索称为执行路径(execution path)。查询优化的技巧就是在众多可用的方式中选择一种最有效的方式来获得数据。
例如,即使对于只涉及一个表的查询,Oracle也会采用下列方法之一:
·使用索引来查找所请求的行的ROWID,然后从表中检索这些行。
·对表进行扫描并检索行,称为完全表扫描(full table scan)
虽然在通常情况下,使用索引来检索数据要快得多,但在索引获取值的过程中涉及到一个附加的I/O步骤来处理查询。利用索引值来选择满足要求的行所需的I/O操作较少,比从表中获取数据然后对数据执行选择条件的效率高得多。
确定优化查询执行计划的另一个因数在于查询中是否包含ORDER BY条件,从而使之能够按预排序索引自动实现。相反的,如果表很小,优化器可能选择读数据库中所有的记录,而不是索引。
有两种Oracle查询优化器可供选择:基于规则的优化器和基于开销的优化器
基于规则的优化器
使用预先定义的规则集作为查询优化的主要决策依据。
它的一个缺点是过分简单化的规则集。该优化器有大约二十条规则,每个规则的权值相同。对于复杂的数据库,基于规则的优化器的简单规则无法做出最佳的选择。
基于规则的优化器对每个可能的路径都赋予一个优化成绩,然后根据最好的优化成绩来挑选最佳路径。基于规则的优化器另一个缺点是不能确定优化成绩相同时的执行路径,只能依赖SQL语句的语法来解决问题,被选择的执行路径往往由SQL语句中个表出现的先后顺序来决定。
基于开销的优化
为了改进SQL语句的优化性能,Oracle在Oracle7中引入了基于开销的优化器。基于开销的优化器比基于规则的优化器要复杂一些,它通过逻辑I/O操作数最小的原则来选择查询路径。
Oracle8及以后的版本默认优化器为基于开销的优化器。为了正确衡量所有执行计划的开销,基于开销的优化器对有关数据结构的组成进行统计。
统计
基于开销的优化器通过使用自己内部的统计相关的规则和逻辑来反映数据库中数据结构的状态。这些统计与执行计划中的表、列以及索引相关。
这些统计类型存放在数据字典的三个表中
这些统计类型可以单独或组合或二者结合使用,从而确定一个执行计划需要的所有I/O开销。这些统计类型可以反映出表的大小和数据块中没有被使用的空间总量两方面信息;相应的,这些空间反映出检索行所需要的I/O操作次数。索引统计反映索引树的深度与广度,而且反映树中值的唯一性,使用该索引可以简化数据的选择。
Oracle及以后的版本通过SQL语句ANALYZE来搜集这些统计信息。在一个SQL语句中可以对表、索引或集群进行分析。收集统计信息是耗费资源的工作,在某些方面,有点像创建索引。因为本身隐含的效果,ANALYZE命令有下面两个选项:
COMPUTE STATSTICS
在整个数据结构中计算统计数据
ESTIMATE STATISTICS
指定行数或数据结构中的一个百分比来进行统计分析。
对于收集相关统计信息,后一种选项比进行整个数据结构的计算所耗费的资源要少得多。
注意:基于开销的优化器的精度取决于它所使用的统计的精度,因此应该将统计信息的更新作为维护计划的一个标准部分。