为什么要在数据库中创建视图?


Answers:


464

视图提供了许多好处。

1.视图可以隐藏复杂性

如果查询需要连接多个表,或者具有复杂的逻辑或计算,则可以将所有逻辑编码到视图中,然后像在表中一样从视图中进行选择。

2.视图可以用作安全机制

视图可以从一个或多个表中选择某些列和/或行,并且可以在视图上而不是基础表上设置权限。这允许仅显示用户需要查看的数据。

3.视图可以简化对遗留代码的支持

如果您需要重构会破坏大量代码的表,则可以用同名视图替换该表。该视图提供与原始表完全相同的架构,而实际架构已更改。这样可以避免引用该表的遗留代码被破坏,从而使您可以随意更改遗留代码。

这些只是视图如何有用的众多示例中的一部分。


84
第3项是没有其他人指出的原因
MedicineMan

2
我认为第3点最重要的是止损差距。最终,当您要更新旧代码时,不仅需要更改视图背后的代码,还必须更改在视图顶部构建的所有代码。我的2cents
super9

3
3确实是视图最强大的属性。帮助提供逻辑数据独立性的正是这样的事实,即您可以独立于基础逻辑数据库提供与数据库的接口是一个非常强大的概念。
法莱纳

1
@John这项技术债务迟早要还清吗?在10年后,对于10年前写的工程师来说可能并不重要,但对公司来说却很重要。
super9 2010年

更改主数据库以及依赖它的所有内容都是一个糟糕的选择,因为您可能“需要10年”。只有在以后修复它的预期成本大于现在修复它的确定成本时,才应不惜一切代价避免技术债务。
男孩先生2010年

88

除其他外,它可以用于安全性。如果您有“客户”表,则可能要授予所有销售人员访问名称,地址,邮政编码等字段的权限,而不是credit_card_number的权限。您可以创建一个视图,该视图仅包括需要访问的列,然后在视图上授予他们访问权限。


有趣。安全性是一个很好的答案。您还有什么“其他事情”?
MedicineMan

13
我以为这个问题的其他答案将描述“其他事情”。:-)
Graeme Perrow

Select name, address, zipcode from customer会达到目的而不是creating a view
PPB

@PranavBilurkar是的,如果您完全控制用户运行的查询。如果用户有能力运行自己的查询(通过一些交互式SQL程序或编写自己的脚本),则可以运行select * from customer它们,从而使他们可以访问所有内容。如果您授予他们访问视图而不是表的权限,则他们将无法访问视图中没有的字段。
Graeme Perrow,

38

视图是查询的封装。转换为视图的查询往往很复杂,因此将其保存为视图以供重用可能是有利的。


因此,当您遇到复杂的查询时,您想创建一个视图吗?查询有多复杂,门槛是多少?从视图中获得什么?
MedicineMan

4
实际上,个人选择有多复杂,没有设定的门槛。例如,如果您不想在多个应用程序或应用程序中的不同点重复逻辑,则通常会使用视图。通过使其成为视图,您可以隐藏该逻辑并能够轻松共享它。
克里斯·卡梅隆·米尔斯

1
您不能对具有选择的存储过程执行相同的操作吗?我是否错误地将存储过程视为存储复杂查询逻辑的一种方式?应该在视图中而不是在存储过程中执行复杂的查询吗?这里的存储过程的优点是什么?
MedicineMan

2
@MedicineMan-存储过程返回一个结果集,而视图表示一个虚拟表,该表允许您在其他查询中用作表。
安德鲁·黑尔

1
我认为关于结果集与虚拟表的这一点似乎是我不理解的关键点。
MedicineMan

28

我通常创建视图以对通常用于报告目的的数据进行非规范化和/或聚合。

编辑

通过详细说明,如果我要拥有一个数据库,其中一些实体是人员,公司,角色,所有者类型,订单,订单明细,地址和电话,人员表中既存储了员工又联系了人,地址和电话表存储了个人和公司的电话号码,开发团队的任务是生成报告(或使非开发人员可以访问报告数据),例如按员工销售,按客户销售,按地区销售,按月销售,按州划分的客户等,我将创建一组视图,这些视图对数据库实体之间的关系进行非规范化,以便可以使用真实世界实体的更集成的视图(无双关语)。一些好处可能包括:

  1. 减少编写查询的冗余
  2. 建立关联实体的标准
  3. 提供机会评估和最大化复杂计算和联接的性能(例如,在MSSQL中的Schemabound视图上建立索引)
  4. 使数据更易于团队成员和非开发人员使用。

1
你能详细说明一下吗?您的答案已被投票否决,但我没有得到其他所有人似乎都拥有的价值
MedicineMan

11

几个原因:如果您有复杂的联接,有时最好有一个视图,这样任何访问都将始终使联接正确,而开发人员则不必记住他们可能需要的所有表。通常,这可能是针对财务应用程序,在该应用程序中,所有财务报告都基于同一组数据非常重要。

如果您有用户要限制他们只能看到的记录,则可以使用视图,仅授予他们访问视图的权限,而不是基础表的访问权限,然后查询该视图

Crystal报表似乎更喜欢使用视图来存储proc,因此执行大量报表编写的人往往会使用很多视图

重构数据库时,视图也非常有用。您通常可以隐藏更改,以便通过创建视图看不到旧代码。阅读重构数据库,以了解它如何工作,因为重构是一种非常强大的方法。


7

与存储过程相比,视图的一个主要优点是您可以像使用表一样使用视图。即,可以在FROM查询的子句中直接引用视图。例如SELECT * FROM dbo.name_of_view

通过几乎所有其他方式,存储过程更加强大。您可以传递参数,包括out参数,让你有效地在一次返回多个值,你可以做SELECTINSERTUPDATE,和DELETE操作,等等,等等

如果您希望View能够从FROM子句中进行查询,但又希望能够传递参数,那么也可以采用这种方法。它称为表值函数。

这是有关该主题的非常有用的文章:

http://databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html

编辑:顺便提一下,这种问题,视图相对于表值函数有什么优势?我没有一个很好的答案,但是我会注意到,用于创建视图的T-SQL语法比用于表值函数的语法更简单,并且数据库的用户可能更熟悉视图。


+1是解决针对SELECT语句的存储过程问题的少数答案之一。您提出表函数的问题是正确的。基本上,视图可能比功能表现更好,因为它们共享相同的引擎。从SQL切换到事务性SQL(即PL / SQL)时,需要支付开销(至少在Oracle中是这样)。但是所有其他内容(安全性,封装性等)同样适用于过程或功能以及视图。
APC

根据视图的结构,可以为某些视图建立索引。这是对表值函数的重大改进。
HLGEM

6

它可以充当ORM与表之间的“中间人”。

例:

我们有一个Person表,我们需要更改它的结构,以便将SomeColumn列移到另一个表,并与它建立一对多的关系。

但是,就Person而言,大多数系统仍将SomeColumn用作单个事物,而不是许多事物。我们使用一个视图将所有SomeColumns放在一起,并将其放在视图中,效果很好。

之所以可行,是因为数据层已更改,但是业务需求没有根本改变,因此不需要更改业务对象。如果必须更改业务对象,我认为这不是一个可行的解决方案,但是观点肯定是一个很好的中点。


1
有趣。在您的情况下,它几乎就像是表的接口。
MedicineMan

5

专注于特定数据 视图使用户可以专注于他们感兴趣的特定数据以及他们负责的特定任务。不必要的数据可以忽略。这也提高了数据的安全性,因为用户只能看到视图中定义的数据,而不能看到基础表中的数据。有关将视图用于安全目的的更多信息,请参见将视图用作安全机制。

简化数据操作 视图可以简化用户操作数据的方式。您可以将常用的联接,投影,UNION查询和SELECT查询定义为视图,以便用户不必在每次对该数据执行附加操作时都指定所有条件和条件。例如,可以将一个复杂的查询用于视图,该查询用于报告目的并执行子查询,外部联接和聚合以从一组表中检索数据。该视图简化了对数据的访问,因为不必在每次生成报告时都编写或提交基础查询。而是查询视图。有关处理数据的更多信息。

您还可以创建内联的用户定义函数,这些函数在逻辑上可以用作参数化视图或具有WHERE子句搜索条件中的参数的视图。有关更多信息,请参见内联用户定义函数。

自定义数据 视图允许不同的用户以不同的方式查看数据,即使他们同时使用相同的数据也是如此。当具有许多不同兴趣和技能水平的用户共享同一数据库时,这特别有利。例如,可以创建一个视图,该视图仅检索与客户经理打交道的客户的数据。该视图可以根据使用该视图的客户经理的登录ID确定要检索的数据。

导出和导入数据 视图可用于将数据导出到其他应用程序。例如,您可能想使用pubs数据库中的store和sales表来使用Microsoft®Excel分析销售数据。为此,您可以基于商店和销售表创建视图。然后,您可以使用bcp实用程序导出视图定义的数据。还可以使用bcp实用程序或BULK INSERT语句将数据从数据文件导入某些视图中,前提是可以使用INSERT语句将行插入视图中。有关将数据复制到视图中的限制的更多信息,请参见INSERT。有关使用bcp实用程序和BULK INSERT语句在视图之间复制数据的更多信息,请参见复制到视图或从视图复制。

合并分区数据 可以在视图中使用Transact-SQL UNION集运算符,以将来自单独表的两个或多个查询的结果合并为一个结果集。对用户而言,它显示为称为分区视图的单个表。例如,如果一个表包含华盛顿的销售数据,而另一个表包含加利福尼亚的销售数据,则可以从这些表的UNION创建视图。该视图代表两个地区的销售数据。要使用分区视图,您可以创建几个相同的表,并指定一个约束条件以确定可以添加到每个表的数据范围。然后使用这些基本表创建视图。查询视图时,SQL Server自动确定哪些表受查询影响,并且仅引用那些表。例如,如果查询指定仅需要华盛顿州的销售数据,则SQL Server仅读取包含华盛顿州销售数据的表;没有其他表被访问。

分区视图可以基于来自多个异构源(例如远程服务器)的数据,而不仅仅是基于同一数据库中的表。例如,要合并来自不同远程服务器的数据,每个远程服务器存储的是组织中不同区域的数据,则可以创建从每个数据源检索数据的分布式查询,然后基于这些分布式查询创建视图。任何查询仅从远程服务器上的表中读取包含查询所请求数据的数据;视图中的分布式查询所引用的其他服务器不会被访问。

在多个表或多个服务器上对数据进行分区时,由于要扫描的数据较少,因此仅访问一部分数据的查询可以运行得更快。如果表位于不同的服务器上或具有多个处理器的计算机上,则还可以并行扫描查询中涉及的每个表,从而提高查询性能。此外,维护任务(例如重建索引或备份表)可以更快地执行。通过使用分区视图,数据仍然显示为单个表,并且可以这样查询而不需要手动引用正确的基础表。

如果满足以下任一条件,则分区视图是可更新的:在视图上定义了INSTEAD OF触发器,该触发器具有支持INSERT,UPDATE和DELETE语句的逻辑。

视图以及INSERT,UPDATE和DELETE语句均遵循为可更新分区视图定义的规则。有关更多信息,请参见创建分区视图。

https://technet.microsoft.com/zh-CN/library/aa214282(v=sql.80).aspx#sql:join


5

这是两个常见原因:

您可以将其用于安全性。在主表上不授予任何权限,并创建限制列或行访问的视图,并向用户授予查看该视图的权限。

您可以方便地使用它。将视图中一直使用的一些表连接在一起。这可以使查询一致且容易。


3

这样做有多个原因。有时,使普通的联接查询变得容易,因为人们可以查询表名而不是进行所有联接。

另一个原因是将数据限制为不同的用户。因此,例如:

表1:列-USER_ID; USERNAME; SSN

管理员用户可以在实际表上使用privs,但是您不想访问的用户说出SSN,则可以将视图创建为

以SELECT user_id的身份创建视图USERNAMES,用户名来自Table1;

然后给他们priv访问视图而不是表的权限。


2

在对旧数据库进行报告时,视图可能是天赐的礼物。特别是,您可以使用敏感的表名,而不是隐含的5个字母名(其中2个是常见的前缀!),或使用充满缩写的列名,这些缩写在当时确定是合理的。


2

通常,我会使用一些视图来简化工作,从存储在多个表中的某个实体获取扩展的详细信息(消除代码中的大量联接以提高可读性),有时还可以在多个数据库中共享数据,甚至使插入更易于阅读。


2

这是如何使用视图和权限来限制用户可以在表中更新的列的方法。

/* This creates the view, limiting user to only 2 columns from MyTestTable */
CREATE VIEW dbo.myTESTview 
WITH SCHEMABINDING AS
SELECT ID, Quantity FROM dbo.MyTestTable;

/* This uses the view to execute an update on the table MyTestTable */
UPDATE dbo.myTESTview
SET Quantity = 7
WHERE ID = 1

1

当我想查看表的快照和/或视图时(以只读方式)


1
“表格快照”是什么意思?您何时或为什么要这样做?
MedicineMan

有很多场景;假设您要在不影响表和下划线的情况下对表运行复杂的查询/存储过程。您创建视图(只读表示)
vehomzzz

因此,如果您要运行复杂的查询存储过程,您是否不能以只读方式访问视图?我真的没有数据库经验来“获得”您在这里所说的内容。您能否详细说明或提供详细示例?
MedicineMan

1

我只在运行查询时喜欢在存储过程中使用视图。视图还可以简化安全性,可以用于简化对多个表的插入/更新,还可以用于快照/实例化数据(运行长时间运行的查询,并保留结果的缓存)。

我已经将物化视图用于运行渴望查询,这些查询不需要实时保持准确。


当您运行查询而不是?为什么?这一点不太合理
MedicineMan

使用视图时,您知道自己仅执行DML操作,调用SP时,在获取数据之前不会发生其他事情。即调用缓存函数,可能会返回缓存的数据集,但这并不意味着您应该将所需的所有数据都调用给SP。它将API简化为数据IMO
MattH,2009年

1

视图还可以将非常复杂的配置和表分解为易于查询的可管理块。在我们的数据库中,整个表管理系统被分解成一个大表的视图。


1

这不能完全回答您的问题,但我认为值得一提的是物化视图。我的经验主要是在Oracle上,但据说SQL-Server相当相似。

我们在体系结构中使用了类似的方法来解决XML性能问题。我们的系统被设计为具有大量以XML形式存储在一行中的数据,应用程序可能需要查询其中的特定值。处理大量XMLTypes并跨大量行运行XPath对性能有很大影响,因此,只要基表发生更改,我们就使用一种物化视图的形式将所需的XML节点提取到关系表中。与标准视图(按需运行查询)不同,这可以在某个时间点有效地提供查询的物理快照。


1

我将存储过程更多地看作是一种可以对数据进行调用的方法,而对我来说,视图提供了一种机制来创建基础数据的综合版本,可以针对该基础版本创建查询或存储过程。当简化或聚合有意义时,我将创建一个视图。当我想提供非常特定的服务时,我将编写一个存储过程。


您能举一些小型服务的例子吗?
MedicineMan

1

关于视图的一个奇怪的事情是,它们被Microsoft Access视为表:当您使用ODBC将Microsoft Access前端附加到SQL数据库时,您会在可用表列表中看到这些表和视图。因此,如果您要在MS Access中准备复杂的报表,则可以让SQL Server进行联接和查询,从而大大简化您的工作。同上,用于在MS Excel中准备查询。


1

我的生产数据库中只有10个左右的视图。我经常使用几个列。我使用的一组数据来自7个表,其中一些具有外部联接,而不必不断重写,我只需要在select中调用该视图并进行一个或2个联接即可。对我来说,这只是节省时间。


如果这超出了问题的范围,请原谅我,但是有几个人提到了这一点-您是否为此招致某种性能损失?
MedicineMan

一点也不。SQL Server优化程序显示了与从视图中选择*完全相同的计划,这与为视图执行SQL连接所做的等同
Brian Spencer 2009年

1

我正在创建xxx,它映射主表(如Products表)和引用表(如ProductType或ProductDescriptionByLanguage)之间的所有关系。这将创建一个视图,使我可以检索产品,并将其所有详细信息从其外键转换为描述。然后,我可以使用ORM创建对象以轻松构建网格,组合框等。



0

我想第一个。隐藏查询的复杂性。它非常适合视图。当我们规范化数据库表时如何增加。当表数量增加时现在要获取数据非常困难。所以最好的处理方法是跟随视图。如果我错了请纠正我。


如果您用谷歌搜索,您将获得有关此问题的非常清晰的信息。
Chella 2012年

0

我们创建视图以限制或限制访问表中的所有行/列。如果所有者希望只需要共享特定或有限的行/列,则他将使用这些列创建一个视图。


这只是您应该/可以使用视图的原因之一。
亚历山大

0

为了安全起见:仅通过一小组视图授予每个用户访问数据库的权限,这些视图包含用户或用户组有权查看的特定数据,从而限制了用户对其他数据的访问。

查询和结构的简单性:视图可以从多个表中提取数据并显示一个表,从而简化信息并将视图的多表查询转换为单表查询,并为用户提供数据库结构的特定视图,数据库是一组特定于特定用户或用户组的虚拟表。

对于创建一致的数据库结构:即使基础源表已更改,视图也呈现一致,不变的数据库结构图像。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.