SQL视图

简介   

 

   视图可以看作定义在SQL Server上的虚拟表.视图正如其名字的含义一样,是另一种查看数据的入口.常规视图本身并不存储实际的数据,而仅仅存储一个Select语句和所涉及表的metadata

       通过视图,客户端不再需要知道底层table的表结构及其之间的关系。视图提供了一个统一访问数据的接口。

     为什么要使用视图(View)

从而我们不难发现,使用视图将会得到如下好处:

 
•   视图隐藏了底层的表结构,简化了数据访问操作 
•   因为隐藏了底层的表结构,所以大大加强了安全性,用户只能看到视图提供的数据 
•   使用视图,方便了权限管理,让用户对视图有权限而不是对底层表有权限进一步加强了安全性 
•   视图提供了一个用户访问的接口,当底层表改变后,改变视图的语句来进行适应,使已经建立在这个视图上客户端程序不受影响 


 视图(View)的分类

    视图在SQL中可以分为三类

1.     普通视图(Regular View) 
2.     索引视图(Indexed View) 
3.     分割视图(Partitioned View) 


   普通视图由一个Select语句所定义,视图仅仅包含其定义和被引用表的metadata.并不实际存储数据。


MSDN中创建视图的模版如下:

     CREATE VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ] 
[ WITH <view_attribute> [ ,...n ] ] 
AS select_statement 
[ WITH CHECK OPTION ] [ ; ]

<view_attribute> ::= 
{
    [ ENCRYPTION ]
    [ SCHEMABINDING ]
    [ VIEW_METADATA ]    
 }



  ENCRYPTION:视图是加密的,如果选上这个选项,则无法修改.创建视图的时候需要将脚本保存,否则再也不能修改了

   SCHEMABINDING:和底层引用到的表进行定义绑定。这个选项选上的话,则视图所引用到的表不能随便更改构架(比如列的数据类型),如果需要更改底层表构架,则先drop或者alter在底层表之上绑定的视图.

   VIEW_METADATA:这个是个很有意思的选项.正如这个选项的名称所指示,如果不选择,返回给客户端的metadata是View所引用表的metadata,如果选择了这个选项,则返回View的metadata.再通俗点解释,VIEW_METADATA可以让视图看起来貌似表一样。View的每一个列的定义等直接告诉客户端,而不是所引用底层表列的定义。

   WITH Check Option:这个选项用于更新数据做限制,下面会在通过视图更新数据一节解释.


SQL视图规则

•   在View中,除非有TOP关键字,否则不能用Order By子句(如果你一意孤行要用Order by,这里有个hack是使用Top 100 percent…..) 
•   View在每个Schema中命名必须独一无二 
•   View嵌套不能超过32层(其实实际工作中谁嵌套超过两层就要被打PP了-.-) 
•   Compute,compute by,INTO关键字不允许出现在View中 
•   View不能建立在临时表上 
•   View不能对全文索引进行查询 


索引视图可以看作是一个和表(Table)等效的对象!

为一个视图加上了聚集索引后。视图就不仅仅再是select语句和表的metadata了,索引视图会将数据物理存在数据库中,索引视图所存的数据和索引视图中所涉及的底层表保持同步。



在SQL Server中实现索引视图是一件非常,简单的事,只需要在现有的视图上加上唯一聚集索引.但SQL Server对于索引视图的限制却使很多DBA对其并不青睐:

    比如:
•索引视图涉及的基本表必须ANSI_NULLS设置为ON 
•索引视图必须设置ANSI_NULLS和QUOTED_INDETIFIER为ON 
•索引视图只能引用基本表 
•SCHEMABINDING必须设置 
•定义索引视图时必须使用Schema.ViewName这样的全名 
•索引视图中不能有子查询 
•avg,max,min,stdev,stdevp,var,varp这些聚合函数不能用 

     ………………


即使你的查询语句中不包含这个索引视图,查询分析器会自动选择这个视图,从而大大的提高了性能.当然,只有在SQL SERVER企业版和开发版才有



分割视图(Partitioned View)

 

    分割视图其实从微观实现方式来说,整个视图所返回的数据由几个平行表(既是几个表有相同的表结构,也就是列和数据类型,但存储的行集合不同)进行UNION连接(对于UNION连接如果不了解,请看我之前的博文)所获得的数据集.

    分割视图总体上可以分为两种:

    1.本地分割视图(Local Partitioned View)

    2.分布式分割视图(Distributed Partitioned View)

               使用分布式分割视图最大的好处就是提升性能
           分布式分割视图所涉及的表之间的主键不能重复
   

  使用分布式分割视图能够在所有情况下都提升性能吗?

         不可能.
         使用这种方式如果面对的查询包含了聚合函数,尤其是聚合函数中还包含distinct。或是不加where条件进行排序.那绝对是性能的杀手。因为聚合函数需要扫描分布式分割视图中所有的表,然后进行UNION操作后再进行运算.

        

       通过视图(View)更新数据

   通过视图更新数据是我所不推荐的.因为视图并不能接受参数.我更推荐使用存储过程来实现.

   使用View更新数据和更新Table中数据的方式完全一样(前面说过,View可以看作是一个虚拟表,如果是索引视图则是具体的一张表)

   通过视图来更新数据需要注意以下几点

   1.视图中From子句之后至少有一个用户表

   2.View的查询无论涉及多少张表,一次只能更新其中一个表的数据

   3.对于表达式计算出来的列,常量列,聚合函数算出来的列无法更新

   4.Group By,Having,Distinct关键字不能影响到的列不能更新


     视图(View)的最佳实践

    这是我个人一些经验,欢迎补充
•   一定要将View中的Select语句性能调到最优(貌似是废话,不过真理都是废话…) 
•   View最好不要嵌套,如果非要嵌套,最多只嵌套一层 
•   能用存储过程和自定义函数替代View的,尽量不要使用View,存储过程会缓存执行计划,性能更优,限制更少 
•   在分割视图上,不要使用聚合函数,尤其是聚合函数还包含了Distinct 
•   在视图内,如果Where子句能加在视图内,不要加在视图外(因为调用视图会返回所有行,然后再筛选,性能杀手,如果你还加上了order by…..) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值