27

我曾经与一位禁止使用 SQL 视图的架构师合作。他的主要原因是视图使粗心的编码人员很容易不必要地涉及连接表,如果编码人员更努力地尝试,可以完全避免这种情况。他隐含地鼓励通过复制粘贴而不是封装在视图中来重用代码。

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

几年后,我可以看到禁令带来的至少一个坏结果——我们有数百个密集、冗长的存储过程,几乎无法维护。

事后看来,我会说这是一个糟糕的决定,但是您对 SQL 视图有何经验?您是否发现它们对性能不利?关于它们何时合适或不合适的任何其他想法?

4

13 回答 13

33

视图有一些很好的用途;我经常使用它们进行调优和公开较少标准化的信息集,或者将多个选择的结果联合到一个结果集中。

显然,任何编程工具都可能被错误地使用,但在我的经验中,我想不出任何时候从性能的角度来看,一个调整不佳的视图会导致任何类型的缺陷,以及它们可以通过提供显式调整的选择和避免提供的价值复杂的 SQL 代码的重复可能很严重。

顺便说一句,我从来都不喜欢基于防止开发人员伤害自己的架构“规则”。这些规则通常有意想不到的副作用——我工作的最后一个地方不允许在数据库中使用 NULL,因为开发人员可能会忘记检查 null。这最终迫使我们在针对数据库构建的所有软件中解决“1/1/1900”日期和默认为“0”的整数,并引入了由开发​​人员在 NULL 是适当值的地方工作引起的一连串错误.

于 2008-09-03T21:28:34.747 回答
20

您已经回答了自己的问题:

他鼓励通过复制和粘贴来重用代码

通过创建视图重用代码。如果视图表现不佳,与在多个地方有相同的表现不佳的代码相比,追踪起来要容易得多。

于 2008-09-03T21:21:31.097 回答
18

不是观点的忠实拥护者(不记得我上次写一个),但也不会完全禁止它们。如果您的数据库允许您将索引放在视图上而不仅仅是表上,您通常可以提高性能,从而使它们变得更好。如果您正在使用视图,请务必考虑对它们进行索引。

我真的只看到对数据分区的视图和对应用程序非常关键的极其复杂的连接的需求(考虑这里的财务报告,从相同的数据集开始对所有内容都可能很关键)。我确实知道一些报告工具似乎更喜欢视图而不是存储过程。

我非常支持在特定实例中永远不会返回比您需要的更多的记录或字段,并且过度使用视图往往会使人们返回比他们需要的更多的字段(并且在太多的情况下,太多的连接),这会浪费系统资源.

我也倾向于看到依赖视图的人(不是视图的开发人员 - 只使用它们的人)通常不太了解数据库(所以如果不使用视图,他们会得到错误的连接)和对我来说,这对于针对数据库编写好的代码至关重要。我希望人们了解他们要求数据库做什么,而不是依赖于一些神奇的黑匣子视图。当然,这都是个人意见,您的里程可能会有所不同。

像 BlaM 一样,我个人没有发现它们比存储过程更容易维护。

2010 年 10 月编辑添加:自从我最初写这篇文章以来,我有机会使用一些由沉迷于使用视图的人设计的数据库。更糟糕的是,他们使用了调用视图的视图(最终我们达到了可以调用的表数量的限制)。这是一场表演噩梦。在一个视图中获取记录的简单计数 (*) 需要 8 分钟,而获取数据需要更长的时间。如果您使用视图,请非常小心使用调用其他视图的视图。您将构建一个系统,该系统很可能无法在生产的正常性能负载下工作。在 SQL Server 中,您只能索引不调用其他视图的视图,所以当您在链中使用视图时最终会发生什么,是必须为每个视图构建整个记录集,并且直到您到达最后一个才应用 where 子句标准。您可能需要生成数百万条记录才能看到三个。当您真的只需要加入一次时,您可能会加入同一个表 6 次,您可能会返回比最终结果集中需要的多得多的列。

于 2008-12-12T22:43:42.060 回答
5

我当前的数据库完全充满了无数不超过 5 行的小表。好吧,我可以数他们,但它很混乱。这些表只是保存常量类型值(想想枚举),并且可以很容易地组合成一个表。然后,我制作了模拟我删除的每个表的视图,以确保向后可压缩性。工作得很好。

于 2008-09-03T21:22:11.220 回答
4

与所有权力一样,观点也有其阴暗面。但是,您不能将视图归咎于编写性能不佳的代码的人。此外,视图可以限制某些列的暴露并提供额外的安全性。

于 2008-09-03T21:31:00.823 回答
4

到目前为止还没有提到的一件事是使用视图为最终用户提供数据的逻辑图片,以进行临时报告或类似的报告。

这有两个优点:

  1. 允许用户使用包含他们期望的数据的单个“表”,而不是要求相对非技术用户来计算潜在的复杂连接(因为数据库是规范化的)
  2. 它提供了一种方法来允许某种程度的 ah hoc 访问,而不会将数据或结构暴露给最终用户。

即使使用非临时报告,有时也更容易为包含相关数据的报告系统提供视图,从而将数据的生成与数据的呈现巧妙地分开。

于 2008-09-04T10:15:46.977 回答
3

视图适用于即席查询,当 DBA 需要快速访问数据以查看系统正在发生什么时,他/她会在后台执行这种查询。

但它们可能对生产代码不利。部分原因是无法预测视图需要哪些索引,因为 where 子句可能不同,因此难以调整。此外,您返回的数据通常比使用视图的单个查询实际需要的数据多得多。这些查询中的每一个都可以单独收紧和调整。

在数据分区的情况下,视图的特定用途可能非常有用,所以我并不是说应该完全避免它们。我只是说,如果一个视图可以被一些存储过程替换,那么没有视图会更好。

于 2008-09-03T21:23:27.270 回答
1

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

使用视图,我们可以执行视图并准确查看导出的内容,没有杂物或未知数。它极大地有助于解决不正确的数据导出问题,并将任何复杂的连接隐藏在视图后面。当然,我们使用基于 TERMS 的系统中的一个非常旧的遗留系统,该系统导出到 sql,因此连接比平时复杂一些。

于 2008-09-03T21:23:05.087 回答
1

前段时间,我尝试维护使用从视图构建的视图构建的视图的代码......这对 a** 来说是一个痛苦,所以我对视图有点过敏 :)

我通常更喜欢直接使用表格,特别是对于速度是主要关注点的 Web 应用程序。直接访问表时,您有机会调整 SQL 查询以实现最佳性能。“预编译”/缓存的工作计划可能是视图的优点之一,但在许多情况下,使用所有给定参数和考虑的 where 子句进行即时编译将导致整体处理速度更快。

但是,如果使用得当,这并不能完全排除观点。例如,您可以使用带有“users”表和“users_status”表的视图来获取每个状态的文本解释 - 如果需要的话。但是,如果您不需要解释:使用“用户”表,而不是视图。一如既往:用你的大脑!

于 2008-09-04T10:34:31.050 回答
1

视图有助于我们发挥作用,以供从生产数据库中提取的基于公共 Web 的应用程序使用。简化的安全性是我们看到的主要优势,因为数据库中的表设计可以在同一个表中组合敏感和非敏感数据。存储过程具有很多这种优势,但视图是只读的,具有潜在的互操作优势,并且对于初级人员来说实现起来不太复杂。

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

于 2011-08-19T13:42:06.650 回答
1

从使用 ORM 的应用程序的角度来看,执行自定义查询比在离散映射类型(例如视图)上执行选择要困难得多。

例如,如果您只需要一个表的 5 个字段(比如 30 或 40 个),那么 ORM 框架将创建一个实体来表示该表。

这意味着即使您只需要实体的一些属性,ORM 框架生成的选择查询也会使整个实体焕然一新。另一方面,视图虽然也映射到使用 ORM 框架的实体,但只会带来您需要的数据。

其次,由于 ORM 框架将实体映射到表,实体之间的关系是在客户端生成(和水合)的,这意味着查询必须执行并返回到应用程序,然后这些实体的链接才能在应用程序的运行时发生。

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

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

虽然这种方法很好并且肯定会产生结果,但它有很多负面的方面。手动代码...是手动的;难以维护,实施繁琐,并导致开发人员更多地担心 DB 提供程序 API 与逻辑域模型的细节。更不用说它增加了开发、维护、错误的表面积等的生产时间(它更加费力)成本。

因此,对于任何说观点不好的人,请考虑事情的另一面;那些高高在上的 DBA 最常不知道的东西。

于 2018-01-24T22:55:22.503 回答
0

让我们看看我能不能想出一个蹩脚的比喻......

“我不需要十字螺丝刀。我带着平头和磨床!”

失控的观点会导致长期的痛苦。一方面,调试和修改单个视图定义比发布修改后的代码更容易。

于 2008-09-03T21:33:27.043 回答
0

视图还可以减少复杂查询的大小(以与存储过程相同的方式)。

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

于 2011-11-28T15:13:28.077 回答