2008-09-03 56 views
27

我曾经与禁止使用SQL视图的架构师合作过。他的主要原因是,对于一个毫无思想的编码人员来说,视图太容易不必要地涉及到连接的表格,如果编码人员更努力地尝试,可以完全避免。隐含地说,他鼓励通过复制粘贴来代码重用,而不是在视图中封装。SQL Server视图,祝福还是诅咒?

该数据库有近600个表,并且高度规范化,所以大多数有用的SQL必须是冗长的。

几年后,我可以看到至少有一个禁令的坏结果 - 我们有数百个密集,冗长的存储过程濒临不可维护。

回想起来,我会说这是一个糟糕的决定,但是您对SQL视图有什么经验?你觉得它们对性能不好吗?任何其他想法,当他们是否合适?通过复制和粘贴

重用通过创建一个视图代码

他是令人鼓舞的代码重用:

回答

29

有一些很好用的意见;我已经用它们进行了很多调整,并将更少的标准化信息暴露出来,或者将多个选择的UNION结果显示为单个结果集。

很明显,任何编程工具都可能被错误地使用,但我不能想到任何时候,根据我的经验,从性能角度来看,调整不好的视图会导致任何类型的缺陷,并且他们可以通过显式提供调整选择和避免复制SQL代码的重复可能是重要的。顺便说一下,我从来不是一个建筑“规则”的粉丝,他们是建立在让开发者不受伤害的基础上的。这些规则通常会产生意想不到的副作用 - 我工作的最后一个地方不允许在数据库中使用NULL,因为开发人员可能会忘记检查null。这最终迫使我们在所有针对数据库构建的软件中都要求“1/1/1900”日期和整数默认为“0”,并且引入了由开发​​人员引起的一系列错误,这些错误是在NULL值为合适值的地方工作的。

+7

+1,但我遇到过设计不好的情况导致可怕表现的情况。情况是SQL2K有两个视图执行工会,然后在第三个视图中加入。在这个特定情况下,性能降低了1000倍。 – BlackWasp 2009-02-23 22:18:30

+0

遇到此问题。我们正在为有性能问题的公司提供咨询服务。我们也给他们一个基于PDA的解决方案,以配合他们现有的系统。他们对每张桌子都有一个观点。他们对系统使用的每个查询都有一个视图。而且他们希望我们能够为我们基于PDA的系统访问其数据库所用的每个查询分别提供一个视图。我告诉他们这是一个可怕的想法。我应该继续他们的做事方式吗?我可以将此作为单独的问题发布在SO上。 – 2012-04-11 12:37:17

19

你已经回答了你自己的问题。如果视图执行效果不佳,那么追踪起来要比在几个地方执行相同的性能不佳的代码要容易得多。

5

我目前的数据库完全充斥着无数个不超过5行的小表。那么,我可以指望他们,但它很混乱。这些表只是保持常量类型的值(想想枚举),并可以很容易地组合成一个表。然后我制作了一些视图,模拟了我删除的每个表格,以确保向后紧凑。工作很好。

1

我们使用所有简单数据导出到csv文件的视图。这简化了编写一个程序包并将sql嵌入到程序包中的过程,该程序变得繁琐且难以调试。

使用视图,我们可以执行视图并准确查看导出的内容,没有死锁或未知。它极大地帮助解决了不正确的数据导出问题,并隐藏了视图背后的任何复杂连接。当然,我们使用一个来自基于TERMS的系统的非常古老的遗留系统,该系统导出到sql,所以连接比平常复杂一点。

3

视图对临时查询很有用,DBA在后台需要快速访问数据以查看系统正在发生的情况时在后台执行此操作。

但它们可能对生产代码不利。部分原因在于,由于where子句可能不同,因此很难调整,所以您需要使用视图的索引是不可预知的。另外,对于使用视图的单个查询,您通常会返回比实际需要更多的数据。这些查询中的每一个都可以分别收紧和调整。

对于数据分区情况下视图的具体用途可能非常有用,所以我并不是说他们应该完全避免。我只是说如果一个视图可以被一些存储过程所取代,那么没有视图就会更好。

4

和所有的力量一样,意见有它自己的阴暗面。但是,对于编写不良执行代码的人来说,您不能责怪他们的观点。此外,视图可以限制某些列的暴露并提供额外的安全性。

0

让我们来看看,如果我能想出一个蹩脚的比喻......

“我不需要十字螺丝起子。我随身携带一个平头和研磨机!”

失控意见将导致长期的痛苦。首先,调试和修改单个视图定义比发布修改后的代码更容易。

4

迄今尚未提及的一件事是使用视图为最终用户提供特别报告或类似数据的逻辑图。

这样做有两个优点:

  1. 为了让用户以单一的“表”中的数据,他们预计而是需要相对非技术用户制定出潜在的复杂的连接(因为数据库是归一化)
  2. 它提供了一种手段来允许某种程度的自组织访问而不将数据或结构暴露给最终用户。

即使非临时报告其有时signicantly更容易提供一个视图包含relveant数据,整齐地分离的生产数据来自同一演示文稿的报告制度。

1

前一段时间我一直试图维护使用从意见内置内置意见看法......那是在一个**疼痛代码,所以我有点过敏意见:)

我通常更喜欢直接使用表格,特别是对于速度是主要问题的Web应用程序。当直接访问表时,您有机会调整SQL查询以获得最佳性能。 “预编译”/缓存的工作计划可能是视图的一个优点,但在许多情况下,即时编译包含所有给定的参数,并且考虑的条款将导致更快的处理。

但是,这并不完全排除视图,如果使用得当。例如,如果需要,可以使用一个视图,将“users”表与“users_status”表连接起来,以获取每个状态的文本解释。但是,如果你不需要解释:使用“users”表,而不是视图。一如既往:用你的大脑!

16

不是很大的看法(不记得上次我写了一个),但也不完全禁止它们。如果您的数据库允许您在视图上放置索引,而不仅仅放在桌面上,那么通常可以提高性能,使其更好。如果您正在使用视图,请务必查看它们的索引。

我真的只看到了需要为视图数据分区和极其复杂的连接是给应用程序(这里的财务报告,其中从一切相同的数据集开始可能是批判性思维)真正的关键。我知道一些报表工具似乎更喜欢存储过程的视图。

我是一个很大的支持者,不会在特定实例中返回比您需要的更多记录或字段,并且过度使用视图往往会使人们返回比他们需要的更多字段(并且太多情况下,太多联接)这浪费了系统资源。

我还倾向于看到依赖视图的人(不是视图的开发人员 - 只使用视图的人)往往不能很好地理解数据库(所以如果不使用它们会导致连接错误视图),对我来说,编写针对数据库的良好代码至关重要。我希望人们了解他们要求分贝做什么,而不是依赖视图的一些魔术黑盒子。当然这都是个人意见,你的里程可能会有所不同。

布拉姆一样,我个人还没有发现它们更容易维护比存储的特效。

编辑于2010年10月添加: 由于我原本写这个,我有机会与由沉迷于使用视图的人设计的几个数据库一起工作。更糟糕的是,他们使用调用视图的视图(最终达到可以调用的表的数量限制)的视图。这是一场表演噩梦。花费8分钟在一个视图中获取记录的简单计数(*),并花费更长的时间才能获取数据。如果您使用视图,请谨慎使用调用其他视图的视图。您将构建一个系统,在生产的正常性能负载下很可能无法正常工作。在SQL Server中,您只能索引不调用其他视图的视图,因此当您在链中使用视图时最终发生的情况是,必须为每个视图构建整个记录集,直到找到最后一个应用where子句条件。您可能需要生成数百万条记录才能看到三条记录。如果您真的只需加入一次,您可以连接6次同一张表,但在最终结果集中,您可能会返回比您需要的更多的列数。

0

意见已经由从生产数据库动用公共基于Web的应用一直对我们有帮助在其使用的角色。简化的安全性是我们看到的主要优势,因为数据库中的表设计可能会将同一表中的敏感数据和非敏感数据组合在一起。一个存储过程分享了这个优点,但是这个视图是只读的,具有潜在的互操作优势,对于初级人员来说这是一个不太复杂的事情。

当视图用于最终用户的即席查询此安全抽象的优势也适用;如果我们有一个适当的,扁平化的数据仓库来表示我们的数据,这将不是什么好处。

0

视图还可以减少复杂的查询的大小(以同样的方式存储的特效可以)。

这样可以减少网络带宽非常繁忙的数据库。

0

从使用ORM的应用程序立场来看,执行自定义查询要比在离散映射类型上进行选择要困难得多(例如,视图)。例如,如果只需要5个表中有多个(比如30或40)的字段,ORM框架将创建一个实体来表示表。

这意味着即使您只需要实体的一些属性,ORM框架生成的select查询也会带来整个实体的全部荣耀。另一方面,尽管也映射到具有ORM框架的实体,但只会带来您需要的数据。其次,由于ORM框架将实体映射到表,因此实体之间的关系在客户端生成(并水合),这意味着查询必须执行并返回到应用程序,然后这些实体可以在运行时发生应用程序。

一些框架通过从一个巨型选择中的多个链接实体(具有多个连接)返回数据绕过该框架,在一次调用中引入所有相关表的列。框架内部分解巨大的结果集,并在将这些实体返回给调用者应用程序之前构造链接实体的逻辑表示。

要点是,视图是使用ORM的应用程序的救星。另一种方法是手动进行数据库调用,并手动将结果记录集传递给可用的实体/模型。

虽然这种方法很好,并且肯定会产生结果,但它有许多消极的方面。手动代码...是手动的;难以维护,实施繁琐,并且导致开发人员更多地关注数据库提供者API与逻辑域模型的细节。更不用说,它增加了开发,维护,缺陷表面积等生产时间(其更多的劳动成本)。

因此,对于任何人说视图不好,请考虑事物的另一面;这些高级和强大的DBA最常不知道的东西。