包括视图、常用的数据字典、序列、索引、约束、事务。
(1)、视图(VIEW)也称作虚表,即虚拟的表,是一组数据的逻辑表示
(2)、视图对应于一条SELECT语句,结果集被赋予一个名字,即视图名字
(3)、视图本身并不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发送变化,视图数据也随之变化
(4)、视图分为简单视图与复杂视图
(5)、简单视图:对应的子查询中不包含有关联查询,查询的字段不包含函数、表达式等,没有分组,没有去重;反之则是复杂视图
(6)、视图创建后,可以像操作表一样操作视图,主要是查询
CREATE [OR REPLACE] VIEW view_name[(alias[, alias...])] AS subquery;
--Subquery是SELECT查询语句,对应的表称作基表
(7)、视图在数据库中不存储数据值,即不占空间,只在系统表中存储对视图的定义
(1)、创建视图的语句是CREATE VIEW
(2)、用户必须有CREATE VIEW系统权限,才能创建视图,如果没有权限,会提示:权限不足
(3)、管理员可以通过DCL语句授予用户创建视图的权限
GRANT CREATE VIEW TO tarena;
GRANT...TO...:DCL命令,授予权限
CREATE VIEW:授予任何权限
tarena:权限赋予给谁
(1)、视图是数据库对象之一,所以数据库对象名字不能重复,所以视图名字一般以“v_”开头
(2)、视图在SQL语句中体现的角色与表相同,但视图并不是一张真实存在的表,而只是对应一个SELECT语句的查询结果集,并将其当做表看待而已
(3)、使用视图的目的是简化SQL语句的复杂度,重用子查询,限制数据访问
-- 创建视图,包含数据为10号部门的员工信息
CREATE VIEW v_myemployee_10 AS SELECT id,name,salary,deptno FROM myemployee_liu WHERE deptno=10;
-- 查看视图数据:
SELECT * FROM v_myemployee_10;
(4)、创建视图时,可以给列赋予别名(有函数或表达式必须给别名),当视图对应的子查询中的字段使用了别名,那么该视图中该字段就用别名来命名
(5)、修改视图时,由于视图仅对应一个SELECT语句,所以修改视图就是替换该SELECT语句而已
-- 修改视图
CREATE OR REPLACE VIEW v_myemployee_10 AS SELECT id,name,salary sal,deptno FROM myemployee_liu WHERE deptno=10;
(1)、如果需要经常执行某项复杂查询,可以基于这个复杂查询建立视图,此后查询此视图即可,简化复杂查询
(2)、视图本质上就是一条SELECT语句,所以当访问视图时,只能访问到所对应的SELECT语句中涉及到的列,对基表中的其它列起到安全和保密的作用,限制数据访问
(3)、通过视图将多张表union all成一张逻辑表,作为单独一个数据库对象,实现表的超集
(1)、视图本身并不包含数据,只有基表数据的逻辑映射
(2)、当视图执行DML操作时,实际上是对基表的DML操作
(3)、对视图执行DML操作的基本原则:
-- 插入数据
INSERT INTO v_myemployee_10 (id,name,sal,deptno) VALUES(1001,'JACK',2000,10);
-- 修改JACK的工资为3000
UPDATE v_myemployee_10 SET sal=3000 WHERE name='JACK';
-- 删除JACK
DELETE v_myemployee_10 WHERE name='JACK';
注:视图插入数据时,如果基表字段是不可为空,而视图插入的空值,则会报错
(4)、对视图的DML操作就是对基表操作,那么操作不当可能对基表进行数据污染(视图插入、更新,在视图中可能不显示操作的列)
(5)、删除操作不会对基表产生数据污染
DELETE v_myemployee_10 WHERE deptno=20;
(1)、基本语法:
CRETE [OR REPLACE] VIEW view_name[(alias[, alias...])] AS subquery [WITH CHECK OPTION]
(2)、WITH CHECK OPTION短语表示,通过视图所做的修改,必须在视图的可见范围内
(3)、假设INSERT,新增的记录在视图仍可查看
(4)、假设UPDATE,修改后的结果必须能通过视图查询到
CREATE OR REPLACE VIEW v_myemployee_10 AS SELECT id,name,salary sal,deptno FROM myemployee_liu WHERE deptno=10 WITH CHECK OPTION;
(1)、对简单视图进行DML操作是合法的,但是不安全的
(2)、如没有在视图上执行DML操作的必要,在建立视图时声明为只读来避免这种情况,保证视图对应的基表数据不会被非法修改
CRETE [OR REPLACE] VIEW view_name[(alias[, alias...])] AS subquery [WITH READ ONLY]
CREATE OR REPLACE VIEW v_myemployee_10 AS SELECT id,name,salary sal,deptno FROM myemployee_liu WHERE deptno=10 WITH READ ONLY;
-- 执行插入会报错:无法对只读视图执行 DML 操作
INSERT INTO v_myemployee_10 (id,name,sal,deptno) VALUES(1001,'JACK',2000,10);
创建一个含有公司部门工资情况的视图,内容为:部门编号,部门名称,部门的最高、最低、平均以及工资总和信息
CREATE OR REPLACE VIEW v_dept_sal AS SELECT d.deptno,d.dname,MIN(m.salary) min_sal,MAX(m.salary) man_sal,AVG(m.salary) avg_sal,SUM(m.salary) sum_sal FROM dept d,myemployee_liu m WHERE d.deptno=m.deptno GROUP BY d.deptno,d.dname;
SELECT * FROM v_dept_sal;
-- 查看谁比自己所在部门平均工资高
SELECT m.id,m.name,m.salary FROM myemployee_liu m,v_dept_sal v WHERE m.deptno=v.deptno AND m.salary>v.avg_sal;
(1)、当不需要视图,可以使用DROP VIEW语句删除视图
DROP VIEW view_name;
(2)、视图虽然是存放在数据字典中的独立对象,但视图仅仅是基于表的一个查询定义,所以对视图的删除不会导致基表数据的丢失,不会影响基表数据
DROP VIEW V_MYEMPLOYEE_10;
和视图相关的数据字典
-- 在数据字典user_objects中查询所有视图名称
SELECT object_name FROM user_objects WHERE object_type='VIEW';
-- 查看所有的视图
SELECT TEXT,view_name FROM user_views;
-- 查看所有表
SELECT table_name FROM user_tables;
CREATE SEQUENCE [schema.]sequence_name [START WITH i][INCREMENT BY j][MAXVALUE m | NOMAXVALUE][MINVALUE n | NOMINVALUE][CYCLE | NOCYCLE][CACHE p | NOCACHE]
(1)、sequence_name是序列名,将创建在schema方案下
(2)、序列的第一个序列值是i,步进是j
(3)、如果j是正数,表示递增,如果是负数,表示递减
(4)、CYCLE是否重复利用,NOCYCLE不重复利用
(5)、序列也是数据库对象之一,作用是生成一系列数字
(6)、序列常用与为某张表的主键字段提供值使用
CREATE SEQUENCE seq_myemployee_id START WITH 1 INCREMENT BY 1;
序列支持两个伪列
SELECT seq_myemployee_id.NEXTVAL FROM dual;
SELECT seq_myemployee_id.CURRVAL FROM dual;
-- 使用序列为myemployee_liu表中插入的数据提供主键字段的值
INSERT INTO myemployee_liu (id,name,salary,job,deptno) VALUES(seq_myemployee_id.NEXTVAL,'JACK',3000,'CLERK',10);
(1)、序列可生成的最大值是m,最小值是n
(2)、如果没有设置任何可选参数,序列的第一个值是1,步进是1
(3)、CYCLE表示在递增至最大值或递减至最小值之后是否重用序列,若是递减并有最大值,从最大值开始;若是递增并有最小值,从最小值开始;若没有从START WITH指定的值开始,默认是NOCYCLE
(4)、CACHE用来指定先先预取p个数据在缓存中,以提高序列值的生成效率,默认是20
删除序列语法:
DROP SEQUENCE sequence_name;
(1)、索引是一种运行直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是独立于表的对象,可以存放在与表不同的表空间(TABLESPACE)中
(2)、索引记录中存有索引关键字和指向表中数据的指针(地址)
(3)、对索引进行I/O操作比对表进行操作要少很多
(4)、索引一旦被建立将被Oracle系统自动维护,查询语句中不用指定使用哪个索引
(5)、索引时一种提高查询效率的机制
CREATE [UNIQUE] INDEX index_name ON table(column[, column...]);
--index_name:表示索引名称
--table:表示表名
--column:表示列名,可以建立单列索引或复合索引
--UNIQUE:表示唯一索引
(1)、索引是数据库对象之一
(2)、索引是为了提高查询效率
(3)、索引的统计与应用是数据库自动完成的,只要数据库认为可以使用某个已创建的索引时就会自动应用
-- 在myemployee_liu表的name列上建立索引
CREATE INDEX idx_myemployee_name ON myemployee_liu(name);
注:查询、排序、去重会自动使用字段的索引,LIKE不会使用到索引
(4)、复合索引也叫多列索引,是基于多个列的索引
-- 经常在ORDER BY子句中使用job和salary作为排序依据,可以建立复合索引
CREATE INDEX idx_myemployee_job_salary ON myemployee_liu(job,salary);
-- 当进行查询排序时,会自动应用索引idx_myemployee_job_salary
SELECT id,name,salary,job FROM myemployee_liu ORDER BY job,salary;
(5)、如果需要在myemployee_liu表的name列上执行大小写无关搜索,可以在此列上建立一个基于UPPER函数的索引
CREATE INDEX ind_myemployee_upper ON myemployee_liu(name);
-- 当进行如下查询时,会使用到ind_myemployee_upper
SELECT * FROM myemployee_liu WHERE UPPER(name)='KING';
(1)、如果经常在索引列上执行DML操作,需要定期重建索引,提高索引的空间利用率:
ALTER INDEX index_name REBUILD;
-- 重建索引idx_myemployee_name
ALTER INDEX idx_myemployee_name REBUILD;
(2)、当一个表上有不合理的索引,会导致操作性能下降,删除索引的语法:
DROP INDEX index_name;
注:索引是不可更改的,想更改必须删除重新建
(1)、不要在小表上建立索引(数据量少)
(2)、为经常出现在WHERE子句中的列创建索引
(3)、为经常出现在ORDER BY、DISTINCT后面的字段建立索引,如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致
(4)、为经常作为表的连接条件的列上创建索引
(5)、不要在经常做DML操作的表上建立索引
(6)、限制表上的索引数目,索引并不是越多越好
(7)、删除很少被使用的、不合理的索引
(1)、函数导致索引用不了
(2)、表达式导致索引用不了
(3)、部分隐式数据类型导致索引用不了
(4)、LIKE和SUBSTR
(5)、查询所有的NULL值
(6)、否定形式
(1)、约束(CONSTRAINT)的全称是约束条件,也称作完整性约束条件
(2)、约束是在数据表上强制执行的一些数据校验规则,当执行DML操作时,数据必须符合这些规则,如果不符合则无法执行
(3)、约束条件可以保证表中数据的完整性,保证数据间的商业逻辑
约束条件包括:
(1)、非空约束用于确保字段值不为空
(2)、默认情况下,任何列都允许有空值,但业务逻辑可能会要求某些列不能取空值
(3)、当某个字段被设置了非空约束条件,这个字段中必须存在有效值,即:
CREATE TABLE employees(
eid NUMBER(6),
name VARCHAR2(30) NOT NULL,
salary NUMBER(7,2),
hiredate DATE
CONSTRAINT employees_hiredate_nn NOT NULL
);
注:使用第二种写法可以自定义约束名,便于后续对此约束进行操作
-- 修改表时添加非空约束
ALTER TABLE employees MODIFY (eid NUMBER(6) NOT NULL);
-- 取消非空约束,可以采用重建表或者修改表的方式
ALTER TABLE employees MODIFY (eid NUMBER(6) NULL);
唯一性约束可以保证表中该字段的值任何一条记录都不可以重复,NULL除外
-- 在建表employees1的同时,在eid、email列上创建一个约束条件,并在建表后在name列上建立一个名为employees_name_uk的唯一约束条件
CREATE TABLE employees1(
eid NUMBER(6) UNIQUE,
name VARCHAR2(30),
email VARCHAR2(50),
salary NUMBER(7,2),
hiredate DATE,
CONSTRAINT employees_email_uk UNIQUE(email)
);
INSERT INTO employees1(eid,name,email) VALUES(1,'JACK','[email protected]');
INSERT INTO employees1(eid,name,email) VALUES(NULL,'JACK',NULL);
SELECT * FROM employees1;
-- 在建表之后添加唯一性约束条件
ALTER TABLE employees1 ADD CONSTRAINT employees_name_uk UNIQUE(name);
注:建表后添加唯一性约束,如果报“”找到重复关键字“是因为表中要添加唯一性约束的字段有重复值,删除重复数据即可”
(1)、主键(Primary Key)约束从功能上看相当于非空(NOT NULL)且唯一(UNIQUE)的组合
(2)、主键字段可以是单字段或多字段组合,即:在主键约束下的单字段或者多字段组合上不允许有空值,也不允许有重复值
(3)、主键可以用来在表中唯一的确定一行数据
(4)、一个表上只允许建立一个主键,而其它约束条件则没有明确的个数限制
(1)、主键应是对系统无意义的数据
(2)、永远也不要更新主键,让主键除了唯一标识一行之外,再无其它的用途
(3)、主键不应包含动态变化的数据,如时间戳
(4)、主键应自动生成,不要人为干预,以免使它带有除了唯一标识一行以外的意义
(5)、主键尽量建立在单列上
-- 在建表时添加主键约束条件
CREATE TABLE employees2(
eid NUMBER(6) PRIMARY KEY,
name VARCHAR2(30),
email VARCHAR2(50),
salary NUMBER(7,2),
hiredate DATE
);
INSERT INTO employees2(eid,name) VALUES(1,'JACK');
-- 建表后添加主键约束条件,并自定义约束条件名称
ALTER TABLE employees2 ADD CONSTRAINT employees2_eid_pk PRIMARY KEY(eid);
外键约束条件定义在两个表的字段或一个表的两个字段上,用于保证相关两个字段的关系
-- 建表后建立外键约束条件
CREATE TABLE employees4(
eid NUMBER(6),
name VARCHAR2(30),
salary NUMBER(7,2),
deptno NUMBER(4)
);
ALTER TABLE employees4 ADD CONSTRAINT employees4_deptno_fk FOREIGN KEY(deptno) REFERENCES dept(deptno);
注:给表添加外键报“此列列表的唯一关键字或主键不匹配”是因为参照表的字段不是主键
外键约束对一致性的维护
-- 对设置了外键的employees4表插入数据
INSERT INTO employees4(eid,name,deptno) VALUES(1234,'ROSE TYLER',40);
INSERT INTO employees4(eid,name,deptno) VALUES(1234,'MARTHA JONES',NULL);
-- 插入外键参照表中不存在的值,会报错"违反完整性约束条件"
INSERT INTO employees4(eid,name,deptno) VALUES(1235,'DONNA NOBLE',50);
-- 删除参照表dept中被外键使用的40号部门数据时会报错"违反完整性约束条件"
DELETE FROM dept WHERE deptno=40;
注:被外键参照的表,要删除被外键表使用的值的列时,需要将外键表中引用这个值的列都删除
(1)、如果在一个频繁DML操作的表上建立外键,每次DML操作,都将导致数据库自动对外键所关联的对应表做检查,产生开销,如果已在程序中控制逻辑,这些判断将增加额外负担,可以省去
(2)、外键确定了主从表的先后生成关系,有时会影响业务逻辑
(1)、保证数据完整性可由程序或触发器控制
(2)、简化开发,维护数据时不用考虑外键约束
(3)、大量数据DML操作时不需要外键耗费时间
(1)、检查(Check)约束条件用来强制在字段上的每个值都要满足Check中定义的条件
(2)、当定义了Check约束的列新增或修改数据时,数据必须符合Check约束中定义的条件
(3)、以下条件表达式不允许:
-- 员工的薪水必须大于2000元
ALTER TABLE employees4 ADD CONSTRAINT employees4_salary_check CHECK(salary>2000);
-- 正常插入数据
INSERT INTO employees4(eid,name,salary,deptno) VALUES(1236,'DONNA NOBLE',2500,40);
-- 修改DONNA NOBLE员工的薪水为1500,会更新失败报“违反检查约束”
UPDATE employees4 SET salary=1500 WHERE name='DONNA NOBLE';
(1)、事务是由一组DML语句和commit/rollback组成,是改变数据库数据的最小逻辑单元。如果是commit,表示数据入库;如果是rollback,表示取消所有的DML操作
(2)、事务的结束
(3)、事务的开始
(1)、原子性(atomicity)
(2)、一致性(consistency)
(3)、隔离性(isolation)
(4)、持久性(durability)
数据库应用程序中最常用的隔离级别:Read committed
在开发多用户、数据库驱动的应用程序中,关键性的挑战之一是要使并行的访问量达到最大化,同时还要保证每一个用户(会话)可以以一致的方式读取并修改数据
(1)、锁(lock)机制
(2)、多版本一致读
(1)、排他锁(X锁)
(2)、共享锁(S锁)
(1)、为确保并发用户能正确使用与管理共享资源,如表中的记录,oracle引进锁机制
(2)、DML锁:用于保护数据的完整性
(3)、DDL锁:用于保护数据库对象的结构(例如表、索引的结构定义)
(1)、其他事务看不见它的操作结构
(2)、表和行上加的锁不释放,会阻塞其他事务的操作
(3)、它所操作的数据可以恢复到之前的状态
(4)、占用的回滚段资源不释放
(1)、数据的改变就像从未发生一样
(2)、插入的数据没有了,更新和删除的数据都恢复出来
(3)、锁被释放
(1)、用savepoint在当前事务里创建一个保留点
(2)、用rollback to savepoint命令将事务回滚到标记点