哪些视图有好处?


87

我只是想大致了解RDBMSes中使用的视图。也就是说,我知道什么是视图以及如何创建视图。我也知道我过去使用它们的目的。

但我想确保我对视图有用的观点和视图不应该有用的观点有透彻的了解。进一步来说:

  1. 视图有什么用?
    • 在不应该使用某个视图的情况下,是否有任何诱人的意图?
    • 为什么要用视图代替表值函数,反之亦然?
    • 乍一看,有没有可能有用的视图情况?

(根据记录,其中一些问题是故意天真的。这部分是概念检查。)


1
类似的问题张贴在这里:stackoverflow.com/questions/1278521/...
药师

我觉得stackoverflow.com/questions/1278521/…为这个问题提供了更好的答案。
GinTonic

Answers:


42

1)视图有用吗?

IOPO仅在一个地方

•无论您是考虑数据本身还是引用联接表的查询,利用视图都可以避免不必要的冗余。

视图还提供了一个抽象层,以防止直接访问表(以及由此产生的引用物理依赖项的手铐)。实际上,我认为这是一种好习惯1,仅提供对底层数据的抽象访问(使用视图和表值函数),包括诸如1之类的视图。该建议中的“做”;)

CREATE VIEW AS
      SELECT * FROM tblData


2)在任何情况下,当您不应该使用某个视图时,是否有使用它的诱惑?

视图联接的性能曾经是一个令人关注的问题(例如SQL 2000)。我不是专家,但我已经有一段时间没有担心了。(我也无法想到我现在在使用视图联接的位置。)

视图可能过大的另一种情况是,仅从一个调用位置引用该视图,而可以使用派生表代替。就像匿名类型优于.NET中的类一样,如果匿名类型仅使用/引用一次。

    •请参阅http://msdn.microsoft.com/zh-cn/library/ms177634.aspx中的派生表说明

3)为什么要用视图代替表值函数,反之亦然?

(除了性能方面的原因)表值函数在功能上等同于参数化视图。实际上,常见的简单表值函数用例就是将WHERE子句过滤器添加到单个对象中已经存在的视图中。

4)是否有某种情况乍一看并不明显,可能有用呢?

我想不出我头顶的任何非表面用途。(我想如果可以的话,这将使它们显而易见;)

9
我不同意当它是SELECT * FROM tblData时在表上创建视图是有意义的。您能否提供一个解释,为什么这会有所帮助?
注册用户

IOPO-仅在一个地方-这是一个著名的设计短语吗?我似乎找不到很多参考资料?它是否有其他形式,例如DRY?
罗伯特

1
@Robert是的,DRY,规范化,IOPO,这些都是同一哲学的不同风味。
TylerH

45

在某种程度上,视图就像一个界面。您可以随意更改基础表结构,但是视图为代码提供了一种无需更改的方法。

视图是为报表编写者提供简单内容的一种好方法。如果您的企业用户希望通过Crystal Reports之类的东西访问数据,则可以在他们的帐户中为他们提供一些简化数据的视图-甚至可以对其进行非规范化。


21

视图可以用来提供安全性(即:用户可以访问仅访问表中某些列的视图),视图可以为更新,插入等提供额外的安全性。视图还提供了别名列名的方法(就像这样) sp),但视图更多是与实际表隔离的。


18

从某种意义上说,观点非正规化。为了以更有意义的方式提供数据,有时需要进行非规范化。无论如何,这是许多应用程序通过在对象中进行域建模来完成的工作。它们以与业务角度更匹配的方式帮助呈现数据。


-1“视图非正常化”?对不起,但这是无稽之谈,除非以某种方式获得了认可。
某人2010年

18
他们绝对非正规化。如果您有相关表已标准化为3rd标称形式,并且创建了一个视图以“展平”该关系,那么这不是非标准化吗?
Kilhoffer 2010年

11

除了其他陈述之外,视图对于从应用程序中删除更多复杂的SQL查询也很有用。

例如,代替在应用程序中执行以下操作:

sql =“从table1联合中选择a,b,从table2中选择a,b”;

您可以将其抽象为视图:

创建视图union_table1_table2_v作为
选择一个,从表1 b
工会
选择一个,从表2 b

在应用程序代码中,只需执行以下操作:

sql =“从union_table1_table2_v选择a,b”;

同样,如果数据结构发生了变化,则无需更改应用程序代码,重新编译和重新部署。您只需更改数据库中的视图即可。


为什么我要在数据库而不是应用程序中编写复杂的sql?
伊万·维拉比扬

3
您的查询越复杂,将来更改的可能性就越大,部分原因是它只是命中了更多的表。当数据库结构更改时,您还必须更改代码并发布。如果在视图中抽象了这种复杂性,则DBA可以对基础表进行结构更改,而无需更改您的代码。
CodingWithSpike 2012年

11

视图隐藏了数据库的复杂性。它们基于许多原因而非常有用,并且在许多情况下很有用,但是如果您允许用户编写自己的查询和报告,则可以使用它们作为保护措施,以确保他们不会提交设计不当的内容具有令人讨厌的笛卡尔联接的查询会导致数据库服务器瘫痪。


6

OP询问是否有可能使用视图的情况,但这是不合适的。

您不想使用视图代替复杂的联接。也就是说,不要让将问题分解为小块的过程编程习惯会导致您趋向于使用多个连接在一起的视图而不是一个较大的连接。这样做会降低数据库引擎的效率,因为它实际上是在执行几个单独的查询,而不是一个更大的查询。

例如,假设您必须将表A,B,C和D连接在一起。您可能会想从表A和B中创建一个视图,并从表C和D中创建一个视图,然后将这两个视图结合在一起。最好只在一个查询中加入A,B,C和D。


我认为这是不对的,至少这不是DBMS理论的发展方向(各种实现可能决定不遵守该理论)。查询解析器实际上将用相应的sql替换它看到的所有视图,然后优化器将从那里去。这两种情况应等效。
SquareCog

当您可以向视图中添加索引时,这也不成立。
therealhoff

我最熟悉PostgreSQL,而较早的版本在合并查询方面并不是很好。但是新的更好。我的答案已不再适用,至少对于此特定的DBMS而言。
巴里·布朗

5

视图可以集中或合并数据。我在哪里,我们在几个不同的链接服务器上有许多不同的数据库。每个数据库都保存不同应用程序的数据。其中一些数据库保存与许多不同应用程序相关的信息。在这种情况下,我们将在该应用程序的数据库中创建一个视图,该视图仅从实际存储数据的数据库中提取数据,以使我们编写的查询看起来不会跨多个数据库。


4

到目前为止的响应是正确的-视图很适合提供安全性,非规范化(尽管如果做错了,这条道路会很痛苦),数据模型抽象等。

此外,视图通常用于实现业务逻辑(失效用户是指过去40天内未登录的用户)。


如果通过在7个参考表中进行归一化来进行规范化,然后查询仅需要这些参考表之一的内容。这浪费了很多精力。如果您开始加入此类视图,情况将变得更糟。
SquareCog

你确定吗?MSDN说:“当SQL Server处理按名称引用视图的查询时,通常会扩展视图的定义,直到它们仅引用基表为止。此过程称为视图扩展。这是宏扩展的一种形式。” 我可以想象,在扩展过程中,引擎将足够聪明,只包含查询所需的(视图的)基础表。
安东尼2010年

安东尼,想象一下一个查询,例如“从(select foo。*中选择foo_col,从(foo.id = bar.id)上的foo join bar中选择bar。*”)。在此查询中,内部选择是我们的视图。显然,可以安全地删除小节连接(实际上,如果关系不是严格地为1-1,就不能这样)。对于更复杂的查询,这变得更加棘手,我不建议您依靠通用RDBMS来完成所有-修剪SQL Server可以;如果SQL Server可以,我会感到震惊-Oracle?Postgres?和往常一样,如有疑问,请阅读查询计划
SquareCog 2010年

3

视图在您的SQL脚本中保存了许多重复的复杂JOIN语句。您可以将某些复杂的JOIN封装在某些视图中,并在需要时在SELECT语句中调用它。这有时比在每个查询中写出join语句方便,直接并且容易。


2

视图只是一个存储的名为SELECT语句。将视图视为库函数。


存储过程是否更适合这样做?有时,您需要具有删除和更新视图的功能,无法满足这种需求。视图应被视为限制目标用户的抽象或方法。
HumbleWebDev

1

我想强调使用视图进行报告。通常,在规范化数据库表以提高性能(尤其是对于编辑和插入数据(OLTP使用))和取消规范化以减少用于报告和分析的查询的表联接数(OLAP使用)之间存在冲突。必然,OLTP通常会获胜,因为数据输入必须具有最佳性能。然后,创建视图以实现最佳的报告性能,可以帮助满足两类用户(数据输入和报告查看器)的需求。


1

我记得很长的SELECT涉及几个UNION。每个UNION都包含一个价格表的联接,该联接是由SELECT即时创建的,该SELECT本身相当长且难以理解。我认为最好有一个创建价格表的视图。它将使整个SELECT缩短大约一半。

我不知道数据库是否会对视图进行一次评估,或者每次调用一次。有人知道吗 如果是前者,则使用视图将提高性能。


Oracle CBO可以选择一次评估视图(具体化,他们称之为视图),或者将视图的SQL合并到select语句的其余部分中并运行该视图。它将基于较低的估计成本进行决定。
WW。

如果select语句在整个查询过程中是恒定的,并且仅重复几次,则使用公共表表达式(CTE)可以解决问题。这仅适用于SQL Server 2005/2008,因为它在SQL Server 2000中不可用。是的,视图仍将被重复调用。
注册用户

@注册用户:CTE不是SQL Server专业。它们起源于DB2,并且也存在于PostgreSQL中(因为它们很有用,并且符合ISO SQL标准)。无论视图是内联视图还是被视为黑盒,都是特定于实现的,某些RDBMS比其他视图更智能。
某人2010年

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@的 此外,该注释还可以表明这不适用于SQL Server 2000,因为CTE在2005
注册用户2010年

另一种视图替代方法是将价格表预先放在临时表中。
2010年

0

任何时候需要[my_interface]!= [user_interface]。

例:

表A:

  • ID
  • 信息

查看表A:

  • 客户资料

这是您可以向客户隐藏ID并将信息立即重命名为更详细的名称的一种方式。

该视图将使用基础索引作为主键ID,因此您不会看到性能下降,而只是选择查询的更好抽象。

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.