热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

SqlServer基础之(视图)

阅读目录一:视图的优点二:视图的作用三:视图的分类:四:创建视图:五:视图(View)的最佳实践 视图介绍     视图是从一个或者几个基本表(或视图)导出

阅读目录



  • 一:视图的优点

  • 二:视图的作用

  • 三:视图的分类

  • :四:创建视图

  • :五:视图(View)的最佳实践

 视图介绍      

  视图是从一个或者几个基本表(或视图)导出的表。它与基本表不同,是一个虚表。数据库中只存放视图的定义,而不存在视图对应的数据,这些数据仍然存放在原来的基本表中。所以一旦基本表中的数据发生变化,从视图中查询的数据也就随之改变了。从这个意义上讲,视图就像一个窗口,透过它可以看到数据库中自己感兴趣的数据及其变化。

1.1 视图的概述

      视图是从一个或者多个表导出的,它的行为与表非常相似,但视图是一个虚拟表,在视图中可以使用SELECT语句查询数据,以及使用insert、update和delete语句修改记录,对于视图的操作最终转化为对基本数据表的操作。视图不仅可以方便操作,而且可以保障数据库系统的安全性。

 视图一经定义便存储在数据库中,与其相对应的数据并没有像表数据那样在数据库中在存储一份,通过视图看到的数据只是存放在基本表中的数据。可以对其进行增删该查,通过视图对数据修改,基本表数据也对应变化,反之亦然。

回到顶部


一:视图的目的和优点                                                                     

1.聚焦特定数据:使用户只能看到和操作与他们有关的数据,提高了数据的安全性。
2.简化数据操作:使用户不必写复杂的查询语句就可对数据进行操作。
3.定制用户数据:使不同水平的用户能以不同的方式看到不同的数据。
4.合并分离数据:视图可以从水平和垂直方向上分割数据,但原数据库的结构保持不变。

回到顶部


二:视图的作用                                                                     

 1、视图隐藏了底层的表结构,简化了数据访问操作,客户端不再需要知道底层表的结构及其之间的关系。

    2、视图提供了一个统一访问数据的接口。(即可以允许用户通过视图访问数据的安全机制,而不授予用户直接访问底层表的权限)

    3、从而加强了安全性,使用户只能看到视图所显示的数据。

    4、视图还可以被嵌套,一个视图中可以嵌套另一个视图。

回到顶部


三:视图分类                                                                   

    视图在SQL中可以分为三类



  1.      普通视图(Regular View)

  2.      索引视图(Indexed View)

  3.      分割视图(Partitioned View)

回到顶部


四:创建视图                                                                   


普通视图(Rugular View)

   普通视图由一个Select语句所定义,视图仅仅包含其定义和被引用表的metadata.并不实际存储数据。MSDN中创建视图的模版如下:

CREATE VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ]
[ WITH [ ,...n ] ]
AS select_statement
[ WITH CHECK OPTION ] [ ; ]
::=
{
[ ENCRYPTION ]
[ SCHEMABINDING ]
[ VIEW_METADATA ] }

参数还是比较少的,现在解释一下上面的参数:

 

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

 

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

 

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

 

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

 

 

 

   当然了,创建视图除了需要符合上面的语法规则之外,还有一些规则需要遵守:

 



  •    在View中,除非有TOP关键字,否则不能用Order By子句(如果你一意孤行要用Order by,这里有个hack是使用Top 100 percent…..)

  •    View在每个Schema中命名必须独一无二

  •    View嵌套不能超过32层(其实实际工作中谁嵌套超过两层就要被打PP了-.-)

  •    Compute,compute by,INTO关键字不允许出现在View中

  •    View不能建立在临时表上

  •    View不能对全文索引进行查询

   建立View一个简单的例子:

CREATE VIEW v_Test_View1
AS
SELECT TOP 100 * FROM HumanResources.Employee

 视图建立完成后,就可以像访问表一样访问视图了:

SELECT * FROM v_Test_View1

在Management studio中,我创建视图的时候更喜欢用这样一种方法,将会便捷很多:

6

 

7


索引视图(Indexed View)

    在谈到索引视图之前,我突然想起以前看过的一个漫画.话说咱们高端产品买不起,但是省吃俭用攒点钱买个IPhone装装高端总还是可以的吧:

 

      1

 

    其实索引视图也很类似,在普通的视图的基础上,为视图建立唯一聚集索引,这时这个视图就变成了索引视图.套用上面漫画的公式:视图+聚集索引=索引视图

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

    SQL Server中的索引视图和Oracle中的Materialized View是一个概念.想要理解索引视图,必须先理解聚集索引。聚集索引简单来说理解成主键,数据库中中的数据按照主键的顺序物理存储在表中,就像新华字典,默认是按照ABCD….这样的方式进行内容设置。ABCD….就相当于主键.这样就避免了整表扫描从而提高了性能.因此一个表中只能有一个聚集索引。

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

    理解了索引视图的原理之后,我们可以看出,索引视图对于OLAP这种大量数据分析和查询来说,性能将会得到大幅提升。尤其是索引视图中有聚合函数,涉及大量高成本的JOIN,因为聚合函数计算的结果物理存入索引视图,所以当面对大量数据使用到了索引视图之后,并不必要每次都进行聚合运算,这无疑会大大提升性能.

    而同时,每次索引视图所涉及的表进行Update,Insert,Delete操作之后,SQL Server都需要标识出改变的行,让索引视图进行数据同步.所以OLTP这类增删改很多的业务,数据库需要做大量的同步操作,这会降低性能。

    谈完了索引视图的基本原理和好处与坏处之后,来看看在SQL Server中的实现:

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

    比如:



  • 索引视图涉及的基本表必须ANSI_NULLS设置为ON

  • 索引视图必须设置ANSI_NULLS和QUOTED_INDETIFIER为ON

  • 索引视图只能引用基本表

  • SCHEMABINDING必须设置

  • 定义索引视图时必须使用Schema.ViewName这样的全名

  • 索引视图中不能有子查询

  • avg,max,min,stdev,stdevp,var,varp这些聚合函数不能用

     ………………

      还有更多…就不一一列举了,有兴趣的请自行Google之.

      下面我来通过一个例子来说明索引视图:

      假设在adventureWorks数据库中,我们有一个查询:

SELECT p.Name,s.OrderQty
FROM Production.Product p
inner join Sales.SalesOrderDetail s
ON p.ProductID=s.ProductID

    这个查询的执行计划:

    8before

    这时,我建立视图并在这个视图上建立唯一聚集索引:

--建立视图
CREATE VIEW v_Test_IndexedView
WITH SCHEMABINDING
AS
SELECT p.Name,s.OrderQty,s.SalesOrderDetailID
FROM Production.Product p
inner join Sales.SalesOrderDetail s
ON p.ProductID=s.ProductID
GO
--在视图上建立索引
CREATE UNIQUE CLUSTERED INDEX indexedview_test1
ON v_Test_IndexedView(SalesOrderDetailID)

 

   接下来,套用刘谦的台词:见证奇迹的时刻到了,我们再次执行之前的查询:

   8after

 

    从上面这个例子中,可以体会到索引视图的强大威力,即使你的查询语句中不包含这个索引视图,查询分析器会自动选择这个视图,从而大大的提高了性能.当然,这么强力的性能,只有在SQL SERVER企业版和开发版才有哦(虽然我见过很多SQL Server的开发人员让公司掏着Enterprise版的钱,用着Express版的功能……)


分割视图(Partitioned View)

 

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

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

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

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

  

    因为本地分割视图仅仅是为了和SQL Server 2005之前的版本的一种向后兼容,所以这里仅仅对分布式分割视图进行说明.

    分布式分割视图其实是将由几个由不同数据源或是相同数据源获得的平行数据集进行连接所获得的,一个简单的概念图如下:

 

    2

   

   上面的视图所获得的数据分别来自三个不同数据源的表,每一个表中只包含四行数据,最终组成了这个分割视图.

    使用分布式分割视图最大的好处就是提升性能.比如上面的例子中,我仅仅想取得ContactID为8这位员工的信息,如果通过分布式视图获取的话,SQL Server可以非常智能的仅仅扫描包含ContactID为8的表2,从而避免了整表扫描。这大大减少了IO操作,从而提升了性能.

    这里要注意的是,分布式分割视图所涉及的表之间的主键不能重复,比如上面的表A ContactID是1-4,则表B的ContactID不能是2-8这个样子.

    还有一点要注意的是,一定要为分布式分割索引的主键加Check约束,从而让SQL Server的查询分析器知道该去扫描哪个表,下面来看个例子.

 

    在微软示例数据库AdventureWorks数据库,我通过ContactID从前100行和100-200行的数据分别存入两个表,Employee100和Employee200,代码如下:

--create Employee100
SELECT TOP 100 * INTO Employee100
FROM HumanResources.Employee
ORDER BY EmployeeID
--create Employee200
SELECT * INTO Employee200
FROM
(SELECT TOP 100 *
FROM HumanResources.Employee
WHERE EmployeeID NOT IN (SELECT TOP 100 EmployeeID FROM HumanResources.Employee ORDER BY EmployeeID)
ORDER BY HumanResources.Employee.EmployeeID)AS e

 

   这时来建立分布式分割视图:

CREATE VIEW v_part_view_test
AS
SELECT * FROM Employee100
UNION
SELECT * FROM Employee200

 

   这时我们对这个索引进行查询操作:

SELECT * FROM v_part_view_test
WHERE EmployeeID=105

  下面是执行计划:

  3

  通过上图可以看出,通过这种分割的方式,执行计划仅仅是扫描Employee200,从而避免了扫描所有数据,这无疑提升了性能.

  所以,当你将不同的数据表之间放到不同的服务器或是使用RAID5磁盘阵列时,分布式分割视图则进一步会提升查询性能.

 

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

 


通过视图(View)更新数据

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

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

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

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

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

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

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

 

   这里说一下创建View有一个WITH Check Option选项,如果选择这个选项,则通过View所更新的数据必须符合View中where子句所限定的条件,比如:

   我创建一个View:

   4

 


视图(View)中的几个小技巧

    1.通过视图名称查到视图的定义

SELECT * FROM sys.sql_modules
WHERE object_id=OBJECT_ID('视图名称')

   2.前面说过,普通视图仅仅存储的是select语句和所引用表的metadata,当底层表数据改变时,有时候视图中表的metadata并没有及时同步,可以通过如下代码进行手动同步

EXEC sp_refreshview 视图名称

回到顶部


五:视图(View)的最佳实践                                                                     

    这是我个人一些经验,欢迎补充



  •    一定要将View中的Select语句性能调到最优(貌似是废话,不过真理都是废话…)

  •    View最好不要嵌套,如果非要嵌套,最多只嵌套一层

  •    能用存储过程和自定义函数替代View的,尽量不要使用View,存储过程会缓存执行计划,性能更优,限制更少

  •    在分割视图上,不要使用聚合函数,尤其是聚合函数还包含了Distinct

  •    在视图内,如果Where子句能加在视图内,不要加在视图外(因为调用视图会返回所有行,然后再筛选,性能杀手,如果你还加上了order by…..)


 

 


原文链接:https://www.cnblogs.com/wll19980306/p/15533487.html



推荐阅读
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了如何使用Power Design(PD)和SQL Server进行数据库反向工程的方法。通过创建数据源、选择要反向工程的数据表,PD可以生成物理模型,进而生成所需的概念模型。该方法适用于SQL Server数据库,对于其他数据库是否适用尚不确定。详细步骤和操作说明可参考本文内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
author-avatar
651404449_724afc
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有