Sql Certificate 简明教程

SQL - Creating Other Schema Objects

除了表之外,视图、序列、索引和同义词等也是必需的架构对象。视图是一个逻辑或虚拟表。同义词只是数据库对象的别名。同义词还可通过对数据库对象的实际名称进行混淆来简化查询编写,并提供系统安全性元素。序列是支持自动生成整数值的特殊数据库对象,且通常用于生成表的 Primar key 值。索引是创建于表列上的,用以方便从表中快速检索信息。

Views

数据库视图是基于查询的逻辑或虚拟表。视图可以像表一样对其进行查询。这意味着,从您作为一个开发人员或数据库系统用户的角度来看,视图看起来像一个表。视图的定义作为一个对象存储于数据库的数据字典中;但是,视图本身不存储数据。数据库还存储用于创建视图的执行计划——这意味着,即使视图的 SELECT 查询呈现的实际数据未作为视图一部分存储,仍可通过使用视图来快速检索数据。相反,每次基于视图定义进行数据库表查询时,都会从视图中“收集”数据——这些称为基本表。

以下给出了通用语法。

CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW [ViewName]
[(Column Alias Name...)]
AS [Query]
[WITH [CHECK OPTION] [READ ONLY] [CONSTRAINT]];

从语法中:

即使视图引用的基本表尚不存在,FORCE 选项仍允许创建视图。此选项用于在实际创建基本表和随附数据之前创建视图。

NOFORCE 选项与 FORCE 相反,并且允许系统用户在具有创建视图所需的权限时创建一个视图,并且创建视图的表已存在。这是默认选项。

WITH READ ONLY 选项允许创建只读视图。您不能使用 DELETE、INSERT 或 UPDATE 命令来修改只读视图的数据。

WITH CHECK OPTION 子句允许更新可通过视图选择的行。它还允许您指定对值的约束。CONSTRAINT 子句与 WITH CHECK OPTION 子句结合使用,以启用数据库管理员为 CHECK OPTION 指定唯一名称。如果数据库管理员省略 CONSTRAINT 子句,那么 Oracle 将自动为约束指定一个系统生成的名称,该名称没有太大的意义。

Types of Views

简单视图仅在单独一个表之上创建。它是一个简单的 SELECT 查询,没有任何函数或 group 子句,只是从表中选择列,而没有任何转换。如果对视图执行 DML,那么它会立刻反映在基本表中。

复杂视图使用联接在多个表上创建。它可以包含 SQL 函数、Group by 函数。但是,由于视图是在多个数据上,并且对列的选择也不是简单的,所以它不允许对其进行 DML 操作。

Illustration

Simple View: 下面这个简单视图为具有 JOB ID 为 DEV 的员工选择员工姓名、部门 ID 和薪水。

CREATE OR REPLACE VIEW v_emp_dev
AS
SELECT first_name, department_id, salary
FROM employees
WHERE job_id = 'DEV';

*复杂视图:*下面的示例显示了该部门的部门名称、在该部门领取的平均薪水和该部门内的员工数量。

CREATE OR REPLACE VIEW EMP_VU
AS
SELECT department_name, AVG (salary) avg_sal, COUNT (first_name) count
FROM employees E, departments D
WHERE E.department_id = D.department_id
GROUP BY department_name;

DESCRIBE [view name] 描述了视图结构。按与视图定义中相同的顺序列出列。

DML operations on a View

能够轻松对简单视图执行 DML 操作。如前所述,插入、更新和删除操作实际上发生在基本表上。

当您对视图执行 UPDATE、DELETE 或 INSERT DML 语句时,您实际上是在处理视图所定义的基本表或表的的数据行。使用 UPDATE、DELETE 和 INSERT 语句与视图存在一定的限制。首先,要将 UPDATE、DELETE 或 INSERT 语句与视图配合使用,视图必须可更新。如果 SELECT 子句未在 SELECT 列表中指定任何聚合函数,那么视图便是可更新的。此外,视图不可能通过使用 GROUP BY、DISTINCT 或 UNION 子句创建。可以在 FROM 子句中的 SELECT 子查询中使用聚合函数。此外,视图在 SELECT 列表中没有任何派生列。其次,如果视图是作为 JOIN 操作(联接视图)的结果创建的,那么 UPDATE 和 INSERT 语句一次只能更新或向基本表之一插入行。您无法用单个数据操作语言 (DML) 语句修改来自两个或更多表的行。最后,DELETE 语句只能针对在 FROM 子句中引用的表的视图执行。这仅仅意味着,您无法删除尚未指定表中的行。

WITH CHECK OPTION clause

WITH CHECK OPTION 是可选子句,它指定通过视图插入或更新数据时要执行的检查级别。如果使用 WITH CHECK OPTION 子句创建视图,那么通过视图在基本表中插入或更新的每一行都必须符合视图定义。请注意,如果视图是只读方式创建的,则无法指定该选项。

例如,为是开发人员(JOB_ID=DEV)的员工创建了视图 V_EMP_DEV。

CREATE OR REPLACE VIEW v_emp_dev
AS
SELECT first_name, department_id, salary,
FROM employees
WHERE job_id = 'DEV'
WITH CHECK OPTION empvu_dev;

用户尝试通过视图更新人力资源员工的薪水,但遇到了异常。这是因为视图是使用 WITH CHECK OPTION 创建的。

UPDATE v_emp_dev
SET salary = salary+500
WHERE JOB_ID = 'HR';
ORA-01402: view WITH CHECK OPTION where-clause violation

如果它是一个简单视图,那么 UPDATE 语句就不会引发任何异常。

Dropping the view

数据库管理员 (DBA) 或视图所有者可以使用 DROP VIEW 语句删除视图。如果视图定义了约束,那么在删除视图时需要指定 CASCADE CONSTRAINTS 子句;否则,DROP VIEW 语句将无法处理。如果其他视图或其他数据库对象(例如同义词或物化视图(本章的后面部分会讨论这两个对象))引用已删除的视图,Oracle 不删除这些数据库对象,而是将它们标记为无效的。你可以删除这些无效的对象或重新定义它们,以便再次使它们生效。

下面的 DROP VIEW 命令从数据库中删除了 EMP_VU 视图。

DROP VIEW EMP_VU;

Sequences

Oracle 提供为这种类型使用生成唯一数字序列的能力,它们被称为序列。一般而言,序列用于生成唯一、连续的整数值,这些值用作数据库表中的主键值。可以生成升序或降序的数字序列。请注意,序列一旦生成的数字无法回滚。

Syntax

CREATE SEQUENCE <sequence name>
[INCREMENT BY < number >]
[START WITH < start value number>]
[MAXVALUE < MAXIMUM VLAUE NUMBER>]
[NOMAXVALUE]
[MINVALUE < minimum value number>]
[CYCLE | NOCYCLE]
[CACHE < number of sequence value to cache> | NOCACHE]
[ORDER | NOORDER];

从语法中:

CREATE SEQUENCE 语句必须指定一个唯一序列名称。这是语句中唯一必需的子句。如果你未指定任何其他子句,则将遵循 Oracle 默认设置生成所有序列号。

INCREMENT BY 子句确定序列在生成每个数字时的增量。默认增量为 1;但是,如果你有充分的理由让序列跳过数字,则可以指定不同的增量。正增量会生成间隔等于你所选间隔的升序序列数。负增量会生成降序序列数。

START WITH 子句指定序列的起始数,默认起始数为 1。此外,如果你已经在将存储序列值作为列的列中含有一些带有数据的行,则必须指定一个起始值。

MAXVALUE 子句指定序列可以增量到的最大值。如果没有指定 MAXVALUE,则序列可以生成的允许最大值为相当大的数字,即 10 的 27 次方 - 1。默认值为 NOMAXVALUE。

MINVALUE 子句指定递减序列(以降序生成数字的序列)的最小值。默认值为 NOMINVALUE。

CYCLE 子句指定如果序列达到指定的 MAXVALUE,则可以重新使用序列值。如果序列循环,则数字将从 START WITH 值重新开始生成。

CACHE 子句可以通过使 Oracle 生成一批指定的序列数字并将其存储在缓存内存中,来提高系统性能。

如果你指定 CACHE,而不指定数字,则默认缓存大小为 20 个序列数字。或者,你可以指定 NOCACHE 以禁止缓存序列数字。

ORDER 子句指定按请求序列号的准确时间顺序分配序列号。

NEXTVAL and CURRVAL

通过使用两个名为 currval 和 nextval 的伪列生成序列值。伪列的行为就像表列,但伪列不会实际存储在表中。当你第一次选择 nextval 伪列时,将返回序列中的初始值。随后选择 nextval 伪列将导致序列按 INCREMENT BY 子句中指定的方式增量,并返回新生成的序列值。currval 伪列返回序列的当前值,即 nextval 上次引用返回的值。

在会话中,NEXTVAL(而不是 CURRVAL)必须是序列上的第一个操作。这是因为在会话中时,当 NEXTVAL 从序列生成该会话的第一个数字,Oracle 将当前值保留在 CURRVAL 中。

Syntax:

Sequence.NEXTVAL
Sequence.CURRVAL

Points to be noted -

  1. CURRVAL 和 NEXTVAL 只能在外层 SQL 中使用 select 语句。

  2. CURRVAL 和 NEXTVAL 可以用于 INSERT 语句,以替换列主键。它可以用作子查询子句,也可以用在 VALUES 子句中。

  3. CURRVAL 和 NEXTVAL 可以用来更新表中的值。

  4. CURRVAL 和 NEXTVAL 不能在 VIEW 选择列表中,使用 DISTINCT 关键字,与 GROUP BY、HAVING 或 ORDER BY 子句一起使用,也不能用作 CREATE TABLE 或 ALTER TABLE 语句中的 DEFAULT 表达式。

Modifying the sequence

序列所有者可以修改序列,以更改属性,如 INCREMENT BY 值、MINVALUE、MAXVALUE、CYCLE 或 CACHE 子句。请注意,所做的更改将反映在后续的数字中。

Syntax:

ALTER SEQUENCE [sequence name]
INCREMENT BY n
MAXVALUE n
NOCACHE
NOCYCLE

Dropping the sequence

DROP SEQUENCE 命令可删除需要重新创建或不再需要的序列。

DROP SEQUENCE [sequence name]

Indexes

索引是用于调整 SELECT 查询性能的数据库对象。索引有多种类型,包括用于实施主键约束、唯一索引、非唯一索引和连接索引的索引。如果没有索引,查询将要求 Oracle 扫描表中的所有行,以便返回结果表所需的那些行。索引是在表列上创建的,然后将索引段下列的所有值存储在该索引中。与序列不同,索引是特定于表的。一旦删除了表,索引就会自动删除。

索引可以自动或手动创建。当您指定 PRIMARY KEY 约束或 UNIQUE 约束时,Oracle 会自动创建唯一索引以支持对指定表的快速数据检索。

或者,用户可以手动创建索引以优化查询性能。手动创建的索引可以是唯一的或非唯一的。非唯一索引可以是 B 树、位图或函数索引。默认情况下,Oracle 会在列上创建 B 树索引。以下是语法:

Syntax

CREATE [UNIQUE][BITMAP]INDEX index
ON table (column [, column]...);

请注意,仅当索引唯一且为位图索引时才必须指定 UNIQUE 和 BITMAP。默认情况下,Oracle 会为普通索引创建 B 树索引。

复合索引(也称为连接索引)是在表的多个列上创建的索引。复合索引中的列可以按任何顺序出现,并且不必是表中的相邻列。对于 WHERE 子句引用复合索引中的所有或前一部分列的查询,复合索引可提高行检索速度。最索引可以包含最多 32 个列。

例如,用户在 EMPLOYEES 表的 HIRE_DATE 列上创建了索引 IDX_EMP。通过遍历索引路径扫描并查找在 HIRE_DATE 列上过滤出的数据,将减少磁盘 I/O。

CREATE INDEX IDX_EMP ON employees(hire_date);

Dropping the Index

索引无法修改,但可以出于分析、重建或统计计算的目的而进行更改。如果必须修改索引定义,则必须删除它并重新创建它。DROP INDEX 命令的语法很简单。

DROP INDEX index_name;

Synonyms

同义词是一个别名,也就是一种简化引用数据库对象任务的速记形式。这个概念类似于对朋友和熟人使用昵称。引用其他用户拥有的对象需要在其前面加上模式名称。在同义词的帮助下,您可以减少连同模式名称一起引用对象所付出的精力。这样,同义词提供了位置透明性,因为同义词名称隐藏了实际对象名称及其所有者。

同义词可分为两类,公有和私有。可以将公有同义词用于允许所有系统用户轻松访问某个对象。事实上,创建公有同义词的个人并不拥有该同义词,而该同义词属于 Oracle 中存在的 PUBLIC 用户组。另一方面,私有同义词属于创建它们的系统用户,并且驻留在该用户的模式中。

Syntax

CREATE [PUBLIC] SYNONYM [synonym name]
FOR OBJECT;

系统用户可以授予其他系统用户使用他们拥有的私有同义词的特权。为了创建同义词,您需要拥有 CREATE SYNONYM 特权。此外,您还必须拥有 CREATE PUBLIC SYNONYM 特权才能创建公有同义词。如果将同义词声明为公有的,则同义词名称不能已经被用作公有同义词。尝试创建已存在的公有同义词时,CREATE PUBLIC SYNONYM 命令会失败,并且 Oracle 会返回 ORA-00955:现有对象使用该名称的错误消息。

Illustration

考虑两个用户 U1 和 U2。U1 有权访问 EMPLOYEES 表。因此,为了让 U2 也能够访问 EMPLOYEES 表,可以在 U2 模式中创建一个同义词。U1 必须向 U2 授予访问权限。

CONN U2/U2
SQL> CREATE SYNONYM EMP_SYN	FOR U1.employees;

CONN U1/U1
SQL> GRANT ALL ON EMP_SYN TO U2;

CONN U2/U2
SQL> SELECT * FROM EMP_SYN;

Dropping a Synonym

用户可以删除自己拥有的同义词。要删除公有同义词,您必须拥有 DROP PUBLIC SYNONYM 特权。

DROP SYNONYM EMP_SYN;