首页 > 代码库 > java线程
java线程
我曾遇到一个项目的数据库中视图比表还要多很多(表和视图加起来上千个),几乎每个表都有对应的视图,而且有很多视图长得相似,比如有些视图关联的表一样,只是查询列表多或少了一两个字段。我敢断定,这就是因为一些水平低劣的开发人员看现有表或视图的数据不完全符合他的需要,就不假思索的拷贝过来改一下然后创建一个新的视图完事儿,久而久之,自然会出现很多相似甚至相同的视图。
在接手上述项目后,真正令我感到崩溃的是,查询语句往往涉及多个视图,且常常是相似的视图定义中又引用了另一个相似的视图,被引用的视图中又引用了另一个相似的视图……。总之就一个字——乱!有时候为了找与页面上字段对应的数据库字段得看完一堆的视图定义才能找到,因此那段时间我特别厌恶视图!并暗下决心:日后如果我能做主,绝不用视图。
后来我换了公司,新接触的项目数据库中基本没用视图。结果没过多久,我便发现代码中有很多相似甚至重复的查询语句,而且代码中的查询语句改起来也比较费劲,于是乎我对视图的主观意识发生了摇摆。我开始问自己:到底该不该用视图?如果用,要怎么用才合理?用了视图到底会降低性能还是会提升性能?
最后我通过阅读《Oracle Database Concepts》并反复实践和揣摩,终于对视图有所感悟。多学一点知识就少一点困惑,而我正是对视图理论方面有了大致了解后才解开对视图的各种困惑。本文第 1 节大部分内容是对官方手册的简化翻译,也夹杂了一些我个人的体会,英语好的读者也可以忽略本节直接阅读原文。
1、视图理论
视图是对一或多个表或其他视图中包含的数据的自定义呈现。视图将查询的输出视为一个表,因此可以认为视图就是存储的查询或虚拟表。视图中包含行和列,就像一个真实的表,但不包含数据本身。视图所引用的表被称为基表,视图总是呈现基表中最近的数据,视图可支持更新数据,所有对视图数据的更新都将被反映到视图的基表中,并受到基表的完整性约束和触发器的约束。
1.1、视图的存储
与表不同,视图不需要分配存储空间,视图也不包含实际数据。视图由查询定义,该查询从视图基表中提取或导出数据。因为视图是基于其他对象的,所以视图只需要在数据字典中存储定义视图的查询,而不需要额外的存储空间。
1.2、视图的作用
可通过视图以不同的形式来显示基表中的数据,而视图的强大之处在于它能够根据不同的用户需求来对基表中的数据进行不同形式的整合。视图的常见用途如下:
1、通过限制对基表中一组指定行或列的访问,来提供额外的安全控制。
2、视图允许通过表连接整合多个表中的相关行或列,构成一个新的数据集,从而达到隐藏数据复杂性的目的。
3、视图提供了从多个表中查询数据,而不必知道如何关联这些表的可能,因而简化了查询的 SQL 语句。
4、重命名视图的列或更改数据形式,不会影响视图所引用的基表,这样一来就能以不同的角度来呈现基表中的数据了。
5、保存复杂的查询,一个查询可能会对表数据进行复杂的计算,如果将这个查询保存为视图,那之后需求进行计算只需查询该视图即可。
6、表达不使用视图无法表达的查询,有时候用户需求过于复杂,几乎写不出来仅从基表中查询数据的单条 SQL 语句,如某些复杂的分组查询、联合查询等。
简单来说,合理运用视图,不仅可以提高数据的安全性,还可以少写代码,提升开发效率和程序的可维护性,也有利于在某些情况下灵活高效的控制数据的展现形式。
1.3、视图的工作机制
Oracle 将定义视图的语句以文本的形式存储在数据字典中。当用户在 SQL 语句中引用了视图时,Oracle 将完成以下三步动作:
1、将引用了视图的语句与视图的定义语句合并成一个语句。
2、在共享 SQL 区解析整合后的语句。
3、执行该语句。
如果共享 SQL 区中存在相似语句,Oracle 就不会重复解析,只有在共享 SQL 区中没有相似语句时,Oracle 才会为该语句创建新的共享 SQL 区。因此引用了视图的 SQL 语句也可能会节约内存进而提高查询性能。
1.4、视图的依赖性
定义视图的查询必须要引用其它对象(表、视图),换而言之,视图依赖于其所引用的对象而存在。Oracle 会自动地处理视图的依赖关系。例如,当用户删除视图的某个基表后再次创建它,Oracle 就会自动的去检查新的基表是否符合现有的视图定义,进而判断视图的有效性。在 PL/SQL Developer 中,所有 Oracle 认为无效的视图都会被打上红叉叉。
1.5、可更新的连接视图
连接视图是指在视图定义的查询的 FROM 字句中引用了多个表或视图的视图,而可更新的连接视图是指能够支持 UPDATE、INSERT 和 DELETE 操作的连接视图。数据字典视图ALL_UPDATABLE_COLUMNS、DBA_UPDATABLE_COLUMNS和USER_UPDATABLE_COLUMNS中包含了那些可更新的视图列信息。如果要确保视图可更新,那么视图定义中就不能包含以下语法结构:
1、集合运算符。
2、DISTINCT 运算符。
3、聚合函数或分析函数。
4、GROUP BY、ORDER BY、CONNECT BY 或 START WITH 子句。
5、SELECT 列表中的集合表达式。
6、SELECT 列表中的子查询。
7、JOIN 连接(也有例外情况)。
Oracle 在对主表进行 DML 操作之后,会通过刷新来维护物化视图中的数据(以确保物化视图和基表中的数据同步)。刷新模式有两种:ON DEMAND 和 ON COMMIT,而刷新方式有四种:FAST、COMPLETE、FORCE 和 NEVER。FAST 刷新采用增量刷新,只刷新自上次刷新以后进行的修改。COMPLETE 刷新对整个物化视图进行完全的刷新。如果选择FORCE 方式,Oracle 会在刷新前先判断下是否可以进行快速刷新,如果可以则采用 FAST 刷新,否则采用 COMPLETE 刷新。NEVER 指物化视图不进行任何刷新。
对于使用快速刷新方法的物化视图,物化视图日志或直接加载日志将保留对主表的更改记录。已经创建好的物化视图也还可以再修改它的刷新方式。物化视图还可以按要求定期刷新。
物化视图日志是将更改同步到主表的模式对象。通过物化视图日志可以逐级刷新主表上定义的物化视图,此过程被称为增量或快速刷新。如果没有物化视图日志,Oracle 必须重新执行物化视图查询来刷新物化视图,这个过程称为完全刷新。通常,快速刷新比完全刷新需要更少的时间。
物化视图日志位于和主表相同模式中的主数据库中。每个主表上最多能定义一个物化视图日志。Oracle 可以根据物化视图日志对所有需要快速刷新的物化视图执行快速刷新。要快速刷新物化连接视图,必须为实例化视图引用的每个表创建一个物化视图日志。
创建物化视图日志:
示例一(创建支持主键实例化视图快速刷新的物化视图日志,并指定物理和存储特性):
更多创建物化视图的细节请参考:《Oracle Database SQL Reference: CREATE MATERIALIZED VIEW》。修改物化视图的细节请参考:《Oracle Database SQL Reference: ALTER MATERIALIZED VIEW》。
java线程