SQLServer之视图简介
视图定义
视图是一个虚拟表,其内容由查询定义。 同表一样,视图包含一系列带有名称的列和行数据。 视图在数据库中并不是以数据值存储集形式存在,除非是索引视图。 行和列数据来*定义视图的查询所引用的表,并且在引用视图时动态生成。
对其中所引用的基础表来说,视图的作用类似于筛选。 定义视图的筛选可以来自当前或其他数据库的一个或多个表,或者其他视图。 分布式查询也可用于定义使用多个异类源数据的视图。 例如,如果有多台不同的服务器分别存储您的单位在不同地区的数据,而您需要将这些服务器上结构相似的数据组合起来,这种方式就很有用。
视图通常用来集中、简化和自定义每个用户对数据库的不同认识。 视图可用作安全机制,方法是允许用户通过视图访问数据,而不授予用户直接访问视图基础表的权限。 视图可用于提供向后兼容接口来模拟曾经存在但其架构已更改的表。 还可以在向 sql server 复制数据和从其中复制数据时使用视图,以便提高性能并对数据进行分区。
视图类型
除了基本用户定义视图的标准角色以外, sql server 还提供了下列类型的视图,这些视图在数据库中起着特殊的作用:
索引视图
索引视图是被具体化了的视图。 这意味着已经对视图定义进行了计算并且生成的数据像表一样存储。 可以为视图创建索引,即对视图创建一个唯一的聚集索引。 索引视图可以显著提高某些类型查询的性能。 索引视图尤其适于聚合许多行的查询。 但它们不太适于经常更新的基本数据集。
分区视图
分区视图在一台或多台服务器间水平连接一组成员表中的分区数据。 这样,数据看上去如同来自于一个表。 联接同一个 sql server 实例中的成员表的视图是一个本地分区视图。
系统视图
系统视图公开目录元数据。 您可以使用系统视图返回与 sql server 实例或在该实例中定义的对象有关的信息。 例如,你可以查询 sys.databases 目录视图以便返回与实例中提供的用户定义数据库有关的信息。 有关详细信息,请参阅系统视图 (transact-sql)。
视图应用场景
可以将视图用于以下用途:
-
集中、简化和自定义每个用户对数据库的认识。
-
用作安全机制,方法是允许用户通过视图访问数据,而不授予用户直接访问底层基表的权限。
-
提供向后兼容接口来模拟架构已更改的表。
-
为最终用户减少数据库呈现的复杂性,客户端只要对视图写简单的代码,就能返回所需要的数据,一些复杂的逻辑操作,放在了视图中来完成。
- 对视图添加一些额外的索引,来提高查询的效率。
- 可以合并分离的数据,创建分区视图。
视图创建注意事项
只能在当前数据库中创建视图。 create view 必须是查询批处理中的第一条语句。 视图最多可以包含 1024 列。
创建视图时,有关该视图的信息将存储在下列目录视图中:sys.views、sys.columns 和 sys.sql_expression_dependencies。create view 语句的文本将存储在 sys.sql_modules 目录视图中。
创建视图时, 数据库引擎将保存 set quoted_identifier 和 set ansi_nulls 的设置。 使用视图时,将使用这些原始设置来分析视图。 因此,访问视图时,set quoted_identifier 和 set ansi_nulls 的任何客户端会话设置都不会影响视图定义。
视图定义中的 select 子句不能包括下列内容:
-
order by 子句,除非在 select 语句的选择列表中也有一个 top 子句。order by 子句仅用于确定视图定义中的 top 或 offset 子句返回的行。 order by 不保证在查询视图时得到有序结果,除非在查询本身中也指定了 order by。
-
into 关键字。
-
option 子句。
-
引用临时表或表变量:
因为 select_statement 使用 select 语句,所以按照 from 子句的指定,使用 <join_hint> 和 <table_hint> 提示是有效的。有关详细信息,请参阅 from (transact-sql) 和 select (transact-sql)。
union 或 union all 分隔的函数和多个 select 语句可在 select_statement 中使用。
check option
要求对该视图执行的所有数据修改语句都必须符合 select_statement 中所设置的条件。 通过视图修改行时,with check option 可确保提交修改后,仍可通过视图看到数据。
视图更新
只要满足下列条件,即可通过视图修改基础基表的数据:
-
任何修改(包括 update、insert 和 delete 语句)都只能引用一个基表的列。
-
视图中被修改的列必须直接引用表列中的基础数据。 不能通过任何其他方式对这些列进行派生,如通过以下方式:
-
聚合函数:avg、count、sum、min、max、grouping、stdev、stdevp、var 和 varp。
-
计算。 不能从使用其他列的表达式中计算该列。 使用集合运算符 union、union all、crossjoin、except 和 intersect 形成的列将计入计算结果,且不可更新。
-
-
被修改的列不受 group by、having 或 distinct 子句的影响。
-
top 在视图的 select_statement 中的任何位置都不会与 with check option 子句一起使用。
上述限制应用于视图的 from 子句中的任何子查询,就像其应用于视图本身一样。 通常情况下, 数据库引擎必须能够明确跟踪从视图定义到一个基表的修改。 有关详细信息,请参阅通过视图修改数据。
如果上述限制妨碍直接通过视图修改数据,则可以考虑以下选项:
-
instead of 触发器
可以对视图创建 instead of 触发器,以使视图可更新。 将执行 instead of 触发器,而不是执行对其定义了触发器的数据修改语句。 此触发器允许用户指定必须发生以处理数据修改语句的操作集合。 因此,如果存在给定的数据修改语句(insert、update 或 delete)的视图的 instead of 触发器,则可通过该语句更新相应的视图。 有关 instead of 触发器的详细信息,请参阅 dml 触发器。
-
分区视图
如果视图为分区视图,则可遵循某些限制对其进行更新。 必要时, 数据库引擎将本地分区视图辨别为所有参与表和视图都在同一 sql server 实例上的视图,而将分布式分区视图辨别为视图中至少有一个表驻留在其他或远程服务器上的视图。
视图优缺点
优点:
1、向视图添加 sql 函数、where 以及 join 语句,也可以提交数据,就像这些来自于某个单一的表。
2、数据安全。
3、可以给视图加密。
4、视图还可以被嵌套,一个视图中可以嵌套另一个视图。
缺点:
1、性能:sql server必须把视图的查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,sql server也把它变成一个复杂的结合体,需要花费一定的时间。
2、修改限制:当用户试图修改视图的某些行时,sql server必须把它转化为对基本表的某些行的修改。对于简单视图来说,这是很方便的,但是,对于比较复杂的视图,可能是不可修改的。
3、数据库表结构的修改可能需要修改相应的视图,维护和迁移麻烦。