博主QQ:819594300
博客地址:http://zpf666.blog.51cto.com/
有什么疑问的朋友可以联系博主,博主会帮你们解答,谢谢支持!
前言:本次内容的相关知识点我们在学习sqlserver2008R2的时候介绍过一些,包括:事务、索引、视图等。那么今天我们学习在oracle上实现这些重要的内容,以实现数据库的优化。
一、事务
1、简介
事务是数据处理的核心,是业务上的一个逻辑单元,它能够保证其中对数据所有的操作,要么全部成功,要么全部失败。DBMS通过事务的管理来协调用户的并发行为,减少用户访问资源的冲突。
![p_w_picpath001.jpg wKiom1kpAk2iiXOXAAE8-31oH_k382.jpg]()
1)显示提交:当事务遇到COMMIT指令时,将结束事务并永久保存所有的更改的数据。
2)显示回滚:当事务遇到ROLLBACK指令时,也将结束事务的执行,但是此时它回滚所有更改的数据到事务开始时的原始值,即取消更改,数据没有变化。
3)DDL语句:一旦用户执行了DDL(数据定义语言,如create,drop等)语句,则之前的所有DML(数据操作语言)操作作为一个事务提交,这种提交称为隐示提交。
4)正常结束程序:如果oracle数据库应用程序正常结束,如使用sqlplus工具更改了数据,而正常退出该程序(exit),则oracle自动提交事务。
5)非正常地结束程序:当程序崩溃或意外终止时,所有数据更改都被回滚,这种回滚成为隐示回滚。
2、事务的特点
事务有4个特性,简写为ACID特性。
1)原则性:以转账操作为例,转出账户余额减少和转入余额增加是两个DML语句,但是必须作为一个不可分割的完整操作。要么同时成功,要么同时失败,只转出而没有转入显然是不可接受的。
2)一致性:无论是在事务前、事务中、事务后,数据库始终处于一致的状态。例如:转账前分别是2000和1000,总金额是3000,转账300后分别是1700和1300,总金额还是3000.这就叫做一致性。不一致就是在某个时间点查询到的总金额不是3000.
3)隔离性:在某个时间段,肯定有很多人都在转账,每个人的转账都是在自己的事务中,所以在一个数据库中,会有很多事物同时存在。虽然同时存在很多事物,但是事物之间不会相互影响。
4)持久性:如果事物提交成功,则数据修改永远生效,如果是回滚,则数据完全没有没修改,就相当于没有这件事情发生。
3、学会事物的控制
1)使用COMMIT和ROLLBACK实现事物控制
COMMIT:提交事物,把事物中对数据库的修改进行永久保存。
ROLLBACK:回滚事物,取消对数据库所做的任何修改。
![p_w_picpath002.jpg wKiom1kpAlGCpYWvAAFgNSo_yAA432.jpg]()
首先执行插入数据。
![p_w_picpath003.jpg wKioL1kpAlrgbo23AAKcySN_Ag0123.jpg]()
执行COMMIT提交事物,数据将会永久保存。
![p_w_picpath004.jpg wKiom1kpAlvAxHWrAABV5jB5RZw182.jpg]()
再次插入数据,并执行rollback回滚。
![p_w_picpath005.jpg wKioL1kpAl7DDAArAAEfX_ykE7M300.jpg]()
查询没有发现70这一行数据
![p_w_picpath006.jpg wKioL1kpAmKRHf4HAAE7nz1wrwM152.jpg]()
2)使用AUTOCOMMIT实现事物的自动提交
Oracle提供了一种自动提交DML操作的方式,这样一旦用户执行了DML操作,如UPDATE,DELETE等,数据就会自动提交。
例2:使用autocommit实现事物自动提交,设置autocommit为ON
![p_w_picpath007.jpg wKiom1kpAmiD9HeOAAHqiBeSmZk704.jpg]()
说明:只要提前执行了set autocommit on 命令,数据就会自动提交,及时执行了回滚数据也会依然保存。
3)验证隔离性
(1)建立表yuangong,并插入数据。
![p_w_picpath008.jpg wKioL1kpAnKDyCHOAAMEUqXtYls971.jpg]()
此时insert记录的事务并没有提交,没有提交事务就没有真正的完成,此时还有rollback的机会。
(2)查询一下
![p_w_picpath009.jpg wKiom1kpAnfgHi7TAAGXnrKC22Q804.jpg]()
(3)然后打开一个新的sqlplus会话,查看表时会发现并没有新插入的记录,这是事物的隔离性。
![p_w_picpath010.jpg wKiom1kpAnuj-J13AAGlJ6frZnc217.jpg]()
(4)在第一个sqlplus会话中提交事物
![p_w_picpath011.jpg wKioL1kpAnzC884VAABa2_-2vaE136.jpg]()
(5)提交之后才能在第二个会话中看到被插入的第四条记录
![p_w_picpath012.jpg wKiom1kpAoDD-QxAAAFG7e_nawI897.jpg]()
4)验证持久性
一旦使用commit命令来结束某个事务,那么就必须保证数据库不丢失这个事务。在事务进行期间,隔离性的原则要求除了指定会话涉及的用户之外的任何用户都不能查看当前所做的变化。不过事务一旦完成,所有用户都必须能够立即看到所做的变化,同时数据库必须保证这些变化绝不会丢失。Oracle通过使用日志文件来满足这个需求。日志文件具有两种形式:联机重做日志文件,归档重做日志文件。
一个正确配置的oracle数据库是不可能丢失数据的。当然用户的错误(包括不恰当的DML或删除对象)也会造成数据的丢失。DDL语句有自动提交功能(create、drop、truncate、alter)
(1)
![p_w_picpath013.jpg wKioL1kpAobznPtjAAFp2W3JiRw797.jpg]()
(2)新建表students,并插入一条数据
![p_w_picpath014.jpg wKiom1kpAoyBWGStAAJf7TCiBn8014.jpg]()
(3)回滚事务
![p_w_picpath015.jpg wKioL1kpAo6C7aTPAADnCnLNC50819.jpg]()
(4)再次写入数据
![p_w_picpath016.jpg wKioL1kpApGQdK-zAADH0llZiy4496.jpg]()
(5)退出sqlplus
![p_w_picpath017.jpg wKiom1kpApSBsUC8AADn_lLvY5Y820.jpg]()
(6)在另外一个sqlplus中查看students表中的记录,会发现新插入的lisi的记录了。如果使用sqlplus工具更改了数据之后,正常退出sqlplus时,oracle会自动提交事物。
![p_w_picpath018.jpg wKioL1kpApvxogYzAAG2Ha5_CTI849.jpg]()
关于事物的总结:
1. 需要注意的是,Commit:只是用来确认这个数据已经正式的修改了,不一定非得写入硬盘,DBWn什么都不做。执行commit命令时发生的所有物理操作时LGWR进程将日志缓冲区的内容写入磁盘。DBWN进程完全没有执行任何操作。DBWN进程与提交事物处理没有关系,不过最终DBWN进程会将变化的数据块写入磁盘。
2. commit和rollback语句只应于DML语句,我们无法回滚DDL语句。DDL语句一旦被执行就会立即具有持久状态。
3.自动提交和隐式提交:oracle在某些情况下可以进行自动提交:执行DDL语句是一种情况,退出某个用户进程也是一种自动提交。
二、索引
1、索引的含义
Oracle 数据库对象又称模式对象,数据库对象是逻辑结构的集合,最基本的数据库对象是表,索引也是其中之一。其他数据库对象包括:
![p_w_picpath019.jpg wKiom1kpAp7w1ZL9AAEi2cZjaTQ441.jpg]()
索引是oracle的一个对象,是与表关联的可选结构,提供了一种快速访问数据的途径,提高了数据库检索性能。索引使数据库程序无需对整个表进行扫描,就可以在其中找到所需要的数据。就像书的目录,可以通过目录快速查找所需信息,无需阅读整本书。
2、索引的特点
适当地使用索引可以提高查询速度
可以对表的一列或多列建立索引
建立索引的数量没有限制
索引需要磁盘存储,可以指定表空间,由oracle自动维护
索引对用户透明,检索时是否使用索引由oracle自身决定
Oracle数据库管理系统在访问数据时使用以下三种方式:
全表扫描
通过ROWID(行地址,快速访问表的一行)
使用索引
注:当没有索引或者不选择使用索引时就用全表扫描的方式
3、索引的分类
1)B树索引结构
索引的顶部为根,其中包含指向下一级索引的项。下一级为分支块,分支块又指向索引中下一级的块,最低一级的块称为叶节点,其中包含指向表数据行的索引项。叶节点为双向连接,有助于按关键字值得升序和降序扫描索引。
例如:查询id从2到31行的数据
![p_w_picpath020.jpg wKioL1kpAqOCFfNFAAISbFjaQ5M083.jpg]()
上图中使用索引遍历过程如下:
先找到id<=50的分支块,再找到30-40的分支块,在找到id=31对应的索引项,之后通过叶节点双向链接,平行地找到包含id=2的索引块,完成对id的查询。
4、创建索引的语法
create [unique] index 索引名称 on 表名(列名)[tablespace 表空间名称]
解释:
[unique]用于指定唯一索引,默认情况下为非唯一索引
[tablespace]为索引指定表空间
1)创建标准索引
SQL> create index index_name on tablename(columnname)
tablespace index_tbs;
2)重建索引
SQL> alter index index_namerebuld;
3)合并索引碎片
SQL> alter index index_name coalesce
4)删除索引
SQL> drop indexindex_name;
例1:
1)在雇员表(emp)中,为雇员名称(ename)列创建b树索引。
![p_w_picpath021.jpg wKiom1kpAqrRPw-4AAI_w-MLZiE751.jpg]()
5、创建唯一索引
确保在定义索引的列中没有重复值
Oracle 自动在表的主键列上创建唯一索引
使用CREATE UNIQUE INDEX语句创建唯一索引
语法如下:
SQL> CREATE UNIQUE INDEX index_name
ONtablename(columnname);
例:在薪水级别(salgrade)表中,为级别编号grade列创建唯一索引。
![p_w_picpath022.jpg wKiom1kpAq3D2EejAADZR3G5XGI786.jpg]()
6、反向键索引
与常规B树索引相反,反向键索引在保持列顺序的同时反转索引列的字节。反向键索引通过反转索引键的数据值,使得索引的修改平均分布到整个索引树上。主要应用于所多个实例同时访问一个数据库的场景中。如下图:
![p_w_picpath023.jpg wKiom1kpArqjwC_eAANKZawUBAQ097.jpg]()
如果在常规的B树索引情况下,由于两个雇员号empno索引在索引树种的位置相近而处于同一个索引块中,多个实例同时更新时会发生冲突,从而导致i/o访问上的瓶颈。所以这时候可以使用反向键索引。反向键索引通常建立在一些连续增长的列上,如:编号。
例:在雇员emp表中,为雇员编号empno列创建反向键索引。CREATE INDEX emp_empno_reverse_idx ON emp(empno) REVERSE;
![p_w_picpath024.jpg wKiom1kpAsDiiFJiAAHu5zPplNU775.jpg]()
提示此列已经建立索引了,执行下面命令查询索引有哪些:
![p_w_picpath025.jpg wKioL1kpAsSgLIDpAAHwp8nfjeY815.jpg]()
下面查询一下PK_EMP索引是为哪列创建的:
![p_w_picpath026.jpg wKioL1kpAs3g4ykNAAJwxgCId34721.jpg]()
由上图可以看出,PK_EMP索引是为empno列创建的,所以上面创建反向键索引创建不了,说明相同的列不能创建多个索引。
所以要么把PK_EMP索引删除,要么就保留这个索引,不创建反向键索引
那我们现在把原来的PK_EMP删除
![p_w_picpath027.jpg wKiom1kpAtOi-3TIAAHZI1m6-A0833.jpg]()
提示无法删除,因为这个索引的表EMP有主键,想删除索引,必须去掉主键,命令如下:
![p_w_picpath028.jpg wKioL1kpAtfBzjrHAAElMqQX4ro131.jpg]()
然后创建反向键索引:
![p_w_picpath029.jpg wKiom1kpAtvzaI_aAAFyRlu1UPM651.jpg]()
查询建立是否成功:
![p_w_picpath030.jpg wKioL1kpAuKDub9vAAJDcXUs9A8058.jpg]()
![p_w_picpath031.jpg wKiom1kpAumQGyO-AAICUwu5rvs909.jpg]()
7、位图索引
位图索引适合低于基数的列,即该列的值是有限的几个。例如:雇员表中的工种(job)列,即便是几百万条雇员记录,工种也是有限的。Job列可以作为位图索引,类似的还有图书表中的图书类别列等。
![p_w_picpath032.jpg wKioL1kpAvWAhIU0AANFSQUVKcc667.jpg]()
图索引不直接存储ROWID,而是存储字节位到ROWID的映射,减少响应时间,节省空间占用。位图索引不应当在频发发生insert、update、delete操作的表上使用,这是因为单个位图索引指向表的很多数据行,当修改索引项时需要将其指向的数据行全部锁定,这会严重降低数据库的并发处理能力。位图索引适合用于数据仓库和决策支持系统中。
例:在雇员emp表中,为工种(job)列创建位图索引。
基本语法:
CREATE BITMAP INDEX weitu ON emp(job);
![p_w_picpath033.jpg wKiom1kpAyLChXjLAAFEaOmeeG4922.jpg]()
查询一下建立是否成功:
![p_w_picpath034.jpg wKiom1kpAyuAky8IAAJ4yc0rPHc653.jpg]()
![p_w_picpath035.jpg wKioL1kpAzOwEyKlAAJp4Gcm9V4332.jpg]()
8、组合索引
类似sqlserver的复合索引,在表内多列上创建索引。索引中的列不必与表中的列顺序一致,也不必相互邻接。
例:雇员表中部门和职务列上的索引。组合索引的列最多包含32列。
![p_w_picpath036.jpg wKioL1kpAzfgJwMxAAEf_t41r-4287.jpg]()
9、基于函数的索引
需要创建的索引需要使用表中一列或多列的函数或表达式,也可以将基于函数的索引创建为B树索引或位图索引。
基本语法:
SQL> CREATE INDEX emp_ename_upper_idx
ON tablename(UPPER(columnname));
例:在雇员(emp)表中,为雇员名称(ename)列创建小写函数索引。
![p_w_picpath037.jpg wKiom1kpAz2B51JhAAHiFq10MKE133.jpg]()
现在建立基于函数的索引:
![p_w_picpath038.jpg wKiom1kpA0LBgeGUAAFJt_EyLps816.jpg]()
查询一下建立是否成功:
![p_w_picpath039.jpg wKioL1kpA0vSfVU9AALIWWVXcdI191.jpg]()
10、创建索引的原则
频繁搜索的列可以作为索引列
经常排序,分组的列可以作为索引
经常用作连接的列(主键/外键)可以作为索引
将索引放在一个单独的表空间中,不要放在有回退段、临时段和表的表空间中
对于大型索引而言,考虑使用NOLOGIN子句创建大型索引。
根据业务数据发生频率,定期重新生成或重新组织索引,进行碎片整理。
例:将索引放在一个单独的表空间中
1)使用sys登录创建表空间
![p_w_picpath040.jpg wKiom1kpA1KgaNdiAAJ_d-EqVTo095.jpg]()
2)修改索引到表空间。
![p_w_picpath041.jpg wKioL1kpA1jzXRaTAAHU39YuiSw885.jpg]()
3)查询一下是否修改。
![p_w_picpath042.jpg wKiom1kpA1-wHZ-1AAIeMrfAO4o829.jpg]()
由上图可以看出表空间已经改为了new_tbs。
例2:使用nologging子句
![p_w_picpath043.jpg wKioL1kpA22CL1CjAAP_DspTChI461.jpg]()
11、查看索引列相关的信息:索引名、表名、索引列。
![p_w_picpath044.jpg wKioL1kpA3SQIAEWAAIGmrifY88019.jpg]()
12、维护索引
1)重建索引
索引需要维护,如果建立了索引的表中有大量的删除和插入操作,会使得索引很大,因为删除操作后,删除值的索引空间不能被自动重新使用,对于大表和DML操作很频繁的表,索引的维护是很重要的。Oracle提供了rebuild指令来重建索引。使索引空间可以重用删除值所占用的空间,使索引更加紧凑。
![p_w_picpath045.jpg wKiom1kpA3rjNYGhAAHdvbh6SvI693.jpg]()
![p_w_picpath046.jpg wKiom1kpA4GQe5-hAAIj5zbAmAg881.jpg]()
2)合并索引碎片
合并索引碎片可以释放部分磁盘空间,是索引维护的一种重要方式,也是维护磁盘空间的方式,类似于磁盘碎片整理,把不用的空间释放出来再利用。
![p_w_picpath047.jpg wKioL1kpA4fRkEd_AAHTPQHb0Cc492.jpg]()
3)删除索引
![p_w_picpath048.jpg wKiom1kpA4nyc0txAADXvBUKsUc120.jpg]()
三、视图
1、概述
视图是一个虚表,不占用物理空间,因为视图本身的定义语句存储在数据字典里,视图中的数据是一个或多个实际表中获得的。那些用于产生视图的表叫做该视图的基表。一个视图也可以从另一个视图中产生。
2、视图的优点:
1) 提供了另外一种级别的表安全性
2) 隐藏的数据的复杂性:一个视图可能是用多表连接定义的,但用户不需要知道多表连接的语句也可以查询数据。
3) 简化的用户的SQL命令:查询视图的时候不需要写出复杂的查询语句,只需要查询视图名称即可。
4) 隔离基表结构的改变:视图创建好了之后,如果修改了表的结构,也不会影响视图的。
5) 通过重命名列,从另一个角度提供数据:例如在销售系统中,每日下班前要对当日数据进行汇总,在销售人员眼中,该汇总表成为日销售统计表,在财务人眼中,该销售表成为销售日报表。
3、创建视图的语法:
1) CREATE [OR REPLACE] [FORCE] VIEW
view_name[(alias[, alias]...)]
ASselect_statement
[WITH CHECKOPTION]
[WITH READONLY];
解释:
OR REPLACE:如果视图已存在,此选项将重新创建该视图。
FORCE:如果使用此关键字,则无论基表是否存在,都将创建视图。
NOFORCE:这是默认值,如果使用此关键字,则仅当基表存在时才创建视图。
VIEW_NAME:要创建视图的名称
Alias:指定由视图的查询所选择的表达式或列的别名。别名的数目必须与视图所选择的表达式的数目相匹配。
Select_statement:select语句
WITH CHECK OPTION :此选项指定只能插入或更新视图可以访问的行。术语constraint表示为CHECK OPTION约束指定的名称。
WITH READ ONLY:此选项保证不能在此视图上执行任何修改操作。
2)视图中的ORDER BY子句
可以在创建视图时在SELECT语句中使用ORDERBY子句,以便按照特定的顺序进行排序,这样,在查询视图时即使不使用ORDER BY子句,结果集也会按指定的顺序进行排列。
3)创建带有错误的视图
如果在create view语句中使用FORCE选项,即使存在系列情况,oracle也会创建视图。
视图定义的查询引用了一个不存在的表。
视图定义的查询引用了现有表中无效的列。
视图的所有者没有所需的权限。
在这些情况下,oracle仅检查createview语句中的语法错误。如果语法正确,将会创建视图,并将视图的定义存在数据字典中。但是,该视图却不能使用。这种视图被认为是“带错误创建”的。可使用SHOWERRORS VIEW视图名来查看错误。
4、实验案例:对单表视图的操作
1)连接到oracle,使用scott用户登录
2)创建表order_master
![p_w_picpath049.jpg wKiom1kpA5eyxczlAAPFO9eenz4337.jpg]()
3)插入数据
![p_w_picpath050.jpg wKioL1kpA6GyA2NdAALdBn9_Omw383.jpg]()
4)创建订单状态为"p"的视图,提示没有创建视图的权限。
![p_w_picpath051.jpg wKioL1kpA6rjRyyuAAK_2RxlGMc293.jpg]()
5)授予创建视图的权限(使用sys用户登录)
![p_w_picpath052.jpg wKiom1kpA6_DjZbHAAGUrFUXniw934.jpg]()
6)再次创建视图
![p_w_picpath053.jpg wKiom1kpA7nReXXzAALb1qIkUDU362.jpg]()
7)查询视图
![p_w_picpath054.jpg wKioL1kpA7_hfrwHAAHoYt7cbhw449.jpg]()
8)通过视图修改数据,将状态为p的订单修改为d,但是修改完成之后再次查询视图将查不出任何数据,因为修改了创建视图时作为条件的列。
![p_w_picpath055.jpg wKioL1kpA8ShcEXlAAFUsQ2sIuA868.jpg]()
![p_w_picpath056.jpg wKiom1kpA8igUuCWAAFmUaaWUTk260.jpg]()
9)为了避免修改视图后查询不到的现象,使用with_check_option语句创建检查约束,以防止上述情况发生,同时可以使用constraint指定约束名称。
![p_w_picpath057.jpg wKioL1kpA9uyMwCdAAU2MSg_r2s711.jpg]()
10)再次写入数据,并且再次更新(出现违规提示)
![p_w_picpath058.jpg wKiom1kpA-XTS7N-AAMSZ_zpElo917.jpg]()
11)看一下最终结果
![p_w_picpath059.jpg wKiom1kpA-njZRn3AAEKygeJ5RM350.jpg]()
![p_w_picpath060.jpg wKioL1kpA-3jLvShAAFusXXu2c4492.jpg]()
5、实验案例:创建只读视图
1)使用read only创建只读视图
![p_w_picpath061.jpg wKioL1kpA_eCCDcyAALBQ2f3gao497.jpg]()
2)查询视图
![p_w_picpath062.jpg wKiom1kpA_vzA8UwAAFlI6buFeA110.jpg]()
3)再次更新视图,提示无法对只读视图进行dml操作。
![p_w_picpath063.jpg wKiom1kpBAOz9DnaAAI0H0wFIY0634.jpg]()
6、实验案例:创建带有错误的视图
1)使用force创建带有错误的视图,其中venmast表不存在,但是也能创建成功。
![p_w_picpath064.jpg wKioL1kpBArC3IY5AAJQJN_ey7w834.jpg]()
2)创建表
![p_w_picpath065.jpg wKiom1kpBD_gp8YEAAGFgDn1dvE226.jpg]()
3)重新编译现有视图,使其生效。
![p_w_picpath066.jpg wKioL1kpBELyYFR2AADwbbU9yik170.jpg]()
4)测试查询视图
![p_w_picpath067.jpg wKiom1kpBEbQrcipAAE-s27O29Q281.jpg]()
7、创建order by 子句的视图(查询视图之后会自动排序)
![p_w_picpath068.jpg wKioL1kpBEyyWD5IAAHJufCTjM4202.jpg]()
![p_w_picpath069.jpg wKiom1kpBFHQanOkAAG0jKkeHuc109.jpg]()
然后再创建一个降序的:
![p_w_picpath070.jpg wKiom1kpBFmRjgYqAAJQdAPOBbU730.jpg]()
![p_w_picpath071.jpg wKiom1kpBF_Q3psJAAGdoiM-Tc0594.jpg]()
8、DML语句和复杂视图
DML语句是指用于修改数据的insert、delete和update语句。因为视图是一个虚拟的表,所以这些语句也可以与视图一同使用。一般情况下不通过视图修改数据,而是直接修改基表,因为这样条例更清晰。在视图上使用DML语句有如下限制(相对于表)。
1)DML语句只能修改视图中的一个基表。
2)如果过记录的修改违反了基表的约束条件,则将无法更新视图。
3)如果创建的视图包含连接运算符,DISTINCT运算符、集合运算符、聚合函数和groupby子句,则将无法更新视图。
4)如果创建的视图包含伪列表达式,则将无法更新视图。
简单视图基于单个基表,不包括函数和分组函数,那么可以在此视图中进行insert、update、delete操作,这些操作实际上在基表中插入、更新和删除行。
复杂视图从多个表提取数据,包括函数分组函数。复杂视图不一定能进行DML操作。
1)查询视图
通过数据字典user_views可以查询当前用户下创建的视图名称。
![p_w_picpath072.jpg wKioL1kpBGLhWRkuAAESqNliAeA495.jpg]()
2)删除视图
要从数据库中删除视图,可以使用drop view命令。
![p_w_picpath073.jpg wKioL1kpBGjggqlrAAH0CPwVjM8417.jpg]()
9、物化视图
1)物化视图的含义
物化视图是和普通视图相对应的。在oracle使用普通视图时,它会重复执行创建视图的所有sql语句,如果这样的sql语句含有多张表的连接或者order by 子句,而且表数据量很大,则会非常耗时,效率非常低下,为了解决这个问题,oracle提出了物化视图的概念。
简单的讲,物化视图就是具有物理存储的特殊视图,占据物理空间,就像表一样。物化视图是基于表、物化视图等创建的。他需要和源表进行同步,不断地刷新物化视图中的数据。
物化视图中有两个重要概念:查询重写和物化视图的同步。
![p_w_picpath074.jpg wKiom1kpBG2Dl-OKAAF8RapUvAk954.jpg]()
查询重写:
对sql语句进行重写,当用户使用sql语句对基表进行查询时,如果已经建立了基于这些表的物化视图,oracle将自动计算和使用物化视图来完成查询,在某些情况下可以节约查询时间,减少系统i/o。Oracle将这种查询优化技术成为查询重写。参数QUERY_REWRITE_ENABLED决定是否使用重写查询,该参数为布尔型。在创建物化视图需要使用ENABLE_QUERY REWRITE来启动查询重写功能。通过SHOW指令可以查看该参数的值。
![p_w_picpath075.jpg wKioL1kpBHLR14LnAAGHLnm9dUA108.jpg]()
2)物化视图的同步:
物化视图是基于表创建的,所以当基表变化时,需要同步数据以更新物化视图中的数据,这样保持物化视图中的数据和基表的数据一致性。Oracle提供了两种物化视图的刷新方式,决定何时进行刷新,即ON COMMIT方式和ON DEMAND方式。
ON COMMIT方式:指物化视图在对基表的DML操作事务提交的同时进行刷新。
ON DEMAND方式:指物化视图在用户需要的时候进行更新,可以手工通过DBMS_MVIEW.REFRESH等方式来进行刷新,也可以通过JOB定时进行刷新。
选择刷新方式之后,还需要选择一种刷新类型,刷新类型指定刷新时基表与物化视图如何实现数据的同步,oracle提供了以下4种刷新类型。
COMPLETE:对整个物化视图进行完全的刷新。
FAST:采用增量刷新,只刷新自上次刷新后进行的修改。
FORCE:oracle在刷新时会去判断是否可以进行快速刷新,如果可以则采用FAST方式,否则采用COMPLETE方式。
NEVER:物化视图不进行任何刷新。
默认值是FORCE刷新类型。
3)创建物化视图
① 创建物化视图的前提条件
具备创建物化视图的权限,QUERY REWRITE的权限,以及对创建物化视图所涉及的表的访问权限和创建表的权限。
以sys身份登录,之后授予scott用户创建物化视图的权限。
![p_w_picpath076.jpg wKiom1kpBHzhK4IVAAMATh3osNE740.jpg]()
② 创建物化视图日志
物化视图日志是用户选择了FAST刷新类型时使用的,以增量同步基表的变化。
对scott用户的表DETP和表EMP创建物化视图,所以对这两个基表创建物化视图日志。
![p_w_picpath077.jpg wKioL1kpBIPiQNHTAAIk_cJ2TS8433.jpg]()
③ 创建物化视图语句
通过create materializedview 语句创建物化视图,需要注意各个参数的含义
![p_w_picpath078.jpg wKiom1kpBIXwszVfAASexE8kzFk363.jpg]()
查询物化视图:
![p_w_picpath079.jpg wKioL1kpBIaBotmpAAFO4U7XpmU871.jpg]()
④ 删除物化视图
与删除普通视图相似,需要添加一个materialized关键字。
![p_w_picpath080.jpg wKiom1kpBIbwxuoaAADQEPEfMXo182.jpg]()
再次查询视图,提示视图不存在。
![p_w_picpath081.jpg wKioL1kpBIfhuKpmAAEw1r_SySM840.jpg]()
四、序列
序列是用来生成唯一、连续的整数数据库对象。序列通常用来自动生成主键或唯一键的值。序列可以按升序排列,也可以按降序排列,与excel的自动排序,以及sqlserver的标识符是一样的。
1、创建序列
1)使用sys登录授予scott创建序列的权限。
![p_w_picpath082.jpg wKiom1kpBIeSyJ-nAAJT8hEFTOw338.jpg]()
![p_w_picpath083.jpg wKioL1kpBInTZEeuAAQ92BqPQK8249.jpg]()
例1:在scott用户创建序列号,从序号1开始,每次增加1,最大为2000,不循环,再增加会报错。
![p_w_picpath084.jpg wKiom1kpBIvyvEbCAATn9cBpjmA456.jpg]()
2、访问序列
创建了序列之后,可以通过NEXTVAL和CURRVAL伪列来访问该序列的值。可以从伪列中选择值。但是不能操纵他们的值。
NETXVAL:创建序列后第一次使用NEXTVAL时,将返回该序列的初始值。以后再引用NETXVAL时,将使用INCREMENT BY子句的值来增加序列值,并返回这个新值。
CURRVAL:返回序列的当前值,即最后一次引用NEXTVAL时返回的值。
例2:在玩具表中,需要标识列toyid作为标识,不需要有任何含义,可以做为主键。
1)创建表
![p_w_picpath085.jpg wKiom1kpBIuRKJHMAAHPHoT_BKk043.jpg]()
2)插入数据
![p_w_picpath086.jpg wKioL1kpBIyiOvJ-AAItNvnuvco838.jpg]()
3)查询数据
![p_w_picpath087.jpg wKiom1kpBI3yCHY1AADD8hqtFk8858.jpg]()
4)查看序列当前值
![p_w_picpath088.jpg wKioL1kpBI2yU6LCAACnbxSfOTs366.jpg]()
Currval返回序列的当前值,即最后一次引用NEXTVAL时返回的值。
5)测试currval
![p_w_picpath089.jpg wKiom1kpBI3CXVXJAAG4GCIklC4117.jpg]()
![p_w_picpath090.jpg wKioL1kpBI_Ag0KiAAO7I0dVvow885.jpg]()
3、更改序列
Alter sequence命令用于修改序列的定义。如果要进行下列操作,则会修改序列。
设置或删除MINVALUE 或MAXVALUE
修改增量值
修改缓存中的序列号的数目
不能更改序列的START WITH参数
例3: 设置一个新的maxvalue,并为xulie序列打开了cycle。
![p_w_picpath091.jpg wKioL1kpBI-hpwNyAAHRBIsfPGo650.jpg]()
例4:修改序列为没有最大封顶值
![p_w_picpath092.jpg wKiom1kpBJLhwzmJAAa9C8wnX3A390.jpg]()
例5:将每次增量设置为10
![p_w_picpath093.jpg wKiom1kpBJOxG2GrAAEEfvMzei8992.jpg]()
4、查看序列
可以通过查询名为user_sequences的数据字典视图,来获取用户所创建的序列的详细信息。
![p_w_picpath094.jpg wKioL1kpBJPg8z4qAAKO-XtbvjU436.jpg]()
5、删除序列
DROP SEQUENCE命令用于删除序列。
![p_w_picpath095.jpg wKiom1kpBJTy0beeAAC5YwfKHtM489.jpg]()
五、同义词
同义词是对象的一个别名,不占用任何的实际存储空间,只在oracle的数据字典中保存其定义描述,在使用同义词时,oracle会将其翻译为对应对象的名称。
1、同义词的用途
1)简化sql语句
如果用户创建的表的名字很长,可以为这个表创建一个oracle同义词来简化语句。
2)隐藏对象的名称和所有者
多用户协同开发中,可以屏蔽对象的名称及持有者。如果没有同义词,当操作其他用户的表时,必须通过“用户名.表名”的形式操作,采用了oracle同义词之后就可以隐藏掉用户名。例如:用户user1要访问用户的SCOTT的EMP表,必须使用SCOTT.emp来引用。如果为用户创建一个名为emp的同义词代表SCOTT.emp,那么user1就可以用该同义词像访问自己的表一样引用SCOTT.emp了。
3)为分布式数据库的远程对象提供位置透明性
要完成远程对象的访问,先要了解数据库连接的概念。数据库链接是一个命名的对象,说明一个数据库到另一个数据库的路径,通过其可以实现不同的数据库之间的通信。同义词在数据库链接中的作用就是提供位置透明性。
4)提供对数据库对象的公共访问
公有同义词只是为数据库对象定义了一个公共的别名,即其他用户都可以通过这个别名访问,但能够通过该别名访问成功,还要看是否已经具有数据库对象的访问权限。
2、同义词的分类
同义词分为以下两类:私有同义词和公有同义词
私有同义词只能在其模式内访问,且不能与当前模式的对象同名
公有同义词可被所有的数据库用户访问
2-1:私有同义词
私有同义词只能被当前模式的用户访问,私有同义词名称不可与当前模式的对象名称相同。要在自身的模式创建私有同义词,用户必须拥有create synonym系统权限。要在其他用户模式创建私有同义词,用户必须拥有createany synonym系统权限。
2)创建私有同义词的语法如下:
CREATE [OR REPLACE] SYNONYM [schema.]synonym_name FOR[schema.]object_name;
[OR REPLACE]:在同义词存在的情况下替换该同义词
synonym_name:要创建同义词的名称
object_name:指定要为之创建同义词的对象的名称。
例1:在SYSTEM模式下创建私有同义词访问SCOTT模式下EMP表。
1)以SYSTEM用户身份登录数据库,并访问SCOTT下的EMP表。
![p_w_picpath096.jpg wKioL1kpBJTAjfGLAAJD4Fc5MTQ534.jpg]()
2)以system身份登录数据库,创建同义词。
![p_w_picpath097.jpg wKioL1kpBSHD6y06AAKatcEdmWU170.jpg]()
3)访问同义词tyc,实际访问的是SCOTT的emp表(隐藏了真实的表名,提高了安全性)
![p_w_picpath098.jpg wKiom1kpBSrRWNcSAALNtLPvsRI947.jpg]()
例2:访问网络服务名为orclsv的远程数据库中的表scott.emp
(我这里只有一台服务器,所以我就把自己当做远程服务器,效果是一样的)
1)以SYSTEM用户身份登录数据库,创建数据库连接dblink_sw_orcl来连接远程数据库,其中远程数据库用户名为system,密码为123456,本地网络服务器名为orcl,最后查询远程数据库中的表emp。
![p_w_picpath099.jpg wKioL1kpBS7wtg9-AAEK7AOBQLg488.jpg]()
![p_w_picpath100.jpg wKioL1kpBS-hPfKSAACECB-xHyg852.jpg]()
![p_w_picpath101.jpg wKiom1kpBTDRvD6CAAB4f1Qpv-g505.jpg]()
2)创建私有同义词bieming作为远程数据库表emp的别名
![p_w_picpath102.jpg wKioL1kpBTOwvv5sAADOVG6oZuU839.jpg]()
3)访问同义词bieming,对应的是远程数据库中的表。
![p_w_picpath103.jpg wKiom1kpBTTAH-YOAABKlHLE4XQ379.jpg]()
2-2:公有同义词
公有同义词被所有的数据库访问。公有同义词可以隐藏基表的身份,并降低sql语句的复杂性。要创建公有公有同义词,用户必须拥有create public SYNOYM的系统权限。
例3:在scott模式下对部门表dept创建公有同义词public_sy_dept,目的是使其他用户可以直接访问public_sy_dept。
注意:如果不创建公有同义词,那么其他用户访问scott模式下创建的同义词,一定要加scott前缀,即SCOTT.xxx。如果创建了公有同义词,同义词有了公有属性,那么其他用户都可以使用了。
1)以system用户身份登录数据库,将创建公有同义词权限给SCOTT用户。
![p_w_picpath104.jpg wKiom1kpBTnQKv8JAAG2QiulFCw925.jpg]()
2)以sys用户身份登录,创建一个新用户zpf
![p_w_picpath105.jpg wKioL1kpBULh4YxKAAK1TlKcS6A706.jpg]()
3)以scott用户身份登录数据库,并把查询tmp权限赋予给zpf
![p_w_picpath106.jpg wKioL1kpBUmCBbldAAI4Ds3zhtg675.jpg]()
4)创建公有同义词public_dept作为scott用户dept表的别名
![p_w_picpath107.jpg wKiom1kpBUyzIuDAAAEM9P_nptM860.jpg]()
5)以sys用户的身份登录数据库,赋予给zpf有登录数据库的权限
![p_w_picpath108.jpg wKiom1kpBVKi9qznAAG4mTp1yjM267.jpg]()
6)以zpf身份登录数据库
![p_w_picpath109.jpg wKioL1kpBVmhFaEVAAJAemSXVcU915.jpg]()
3、删除同义词
要删除同义词,用户必须拥有相应的权限。
例:删除同义词tyc和公有同义词public_dept,可以执行如下语句。
1)以sys身份登录,赋予zpf有删除私有和公有同义词的权限
![p_w_picpath110.jpg wKioL1kpBWbh__JLAAPa27Hz6QY546.jpg]()
2)以zpf用户身份登录,来删除system创建的私有同义词tyc和公有同义词public_dept
![p_w_picpath111.jpg wKiom1kpBW-iqbpzAAKr-_8FR2Q615.jpg]()
![p_w_picpath112.jpg wKioL1kpBXSxw8ylAAGwan9n3rk948.jpg]()
六、分区表
1、分区表的含义
Oracle允许把一个表中的所有行分成几个部分,并将它们存储在不同的表空间,分成的每一部分成为一个分区,被分区的表成为分区表。
![p_w_picpath113.jpg wKiom1kpBX7TL1oCAALke0VD7oc249.jpg]()
对于包含大量数据的表来说,分区很有用,优点有以下几点:
1)改善表的查询性能。在对表进行分区后,用户执行sql查询时可以只访问表中的特定分区而非整个表。
2)表更容易管理。因为分区表的数据存储在多个部分中,按分区加载和删除数据比在表中加载和删除更容易。
3)便于备份和恢复。可以独立地备份和恢复每个分区。
4)提高数据安全性。将不同的分区分布在不同的磁盘,可以减少所有分区的数据同时损坏的可能性。
复合一下什么条件的表可以建成分区表:
1)数据量大于2GB。
2)已有的数据和新添加的数据有明显的界限划分。
表分区对用户是透明的,及应用程序可以不知道表已被分区,在更新和查询分区表时当做普通表来操作,但oracle优化程序知道表已被分区。
注意:要分区的表不能具有LONG和LONG RAW数据类型的列。
2、分区表的分类
Oracle提供的分区方法有范围分区、列表分区、散列分区、复合分区、间隔分区和虚拟列分区等。其中间隔分区和虚拟列分区是oracle11g的新特性
范围分区案例:
是一种常用的表分区方法,它是oracle引进的第一个分区类型。范围分区用于可以根据某些条件按范围分开的数据。如果数据均匀的分布在所建立的不同的范围内,那么使用范围分区将得到最好的分区效果。范围可以基于顺序数或部分数,范围分区技术通常基于时间(例如月或季度)
1)创建表并且分区,以age分区
![p_w_picpath114.jpg wKioL1kpBYrBQYRdAAOL27R0zf0998.jpg]()
2)向表中插入数据
![p_w_picpath115.jpg wKioL1kpBY_Ak4PJAAGkyjdm-T4340.jpg]()
3)查询P1区的数据
![p_w_picpath116.jpg wKiom1kpBZOxINkYAAEeOlX7D-0873.jpg]()
查询p200区的数据
![p_w_picpath117.jpg wKioL1kpBZawaxgKAAEOAxL6yEw666.jpg]()
4)如果向表中插入以下记录,会提示插入的分区关键字未映射到任何分区
![p_w_picpath118.jpg wKioL1kpBZzSzfHkAAHbTKtnch4085.jpg]()
5)按范围分区时,如果某些记录暂时无法预测范围,可以创建maxvalue分区,所有不在指定范围内的记录都会被存储到maxvalue所在的分区中。
![p_w_picpath119.jpg wKiom1kpBZ_wMsvPAAEBiCDtAJE487.jpg]()
6)再次插入以下数据
![p_w_picpath120.jpg wKiom1kpBaKC9Z3PAAEBTtt4qss934.jpg]()
7)查询
![p_w_picpath121.jpg wKioL1kpBaSRrkupAADg8c3uy84187.jpg]()
8)查看所有分区的命令
![p_w_picpath122.jpg wKioL1kpCKSBXmWfAAHt-jsvpZU893.jpg]()
一般创建范围分区时都会将最后一个分区设置为maxvalue,将其他数据落入此分区,一旦需要时可以利用拆分分区的技术将需要的数据从最后一个分区分离出入,单独形成一个分区,如果没有创建最大的分区,插入的数据查出范围就会报错。如果插入的数据是分区键上的值,则该数据落入下一个分区,例如:插入数据为20就会落入p2分区。