8

背景

我正在研究一个遗留的小型企业自动化系统(库存、销售、采购等),它有一个由 SQL Server 2005 托管的数据库和一堆客户端应用程序。主客户端(所有用户使用)是一个 MS Access 2003 应用程序 (ADP),其他客户端包括各种 VB/VBA 应用程序,如 Excel 插件和命令行实用程序。

除了大约 60 个表(大部分在 3NF 中)之外,该数据库还包含大约 200 个视图、大约 170 个 UDF(主要是标量和表值内联的 UDF)和大约 50 个存储过程。正如您可能已经猜到的那样,所谓的“业务逻辑”的一部分被封装在大量 T-SQL 代码中(因此被所有客户端共享)。

总的来说,系统的代码(包括 T-SQL 代码)组织得不是很好,可以说是非常抗重构。特别是,大多数表的模式都需要各种重构,小(如列重命名)和大(如规范化)。

FWIW,我有相当长且体面的应用程序开发经验(C/C++、Java、VB 等等),但我不是 DBA。所以,如果这个问题对你来说看起来很傻,现在你知道为什么会这样了。:-)

问题

在考虑重构所有这些混乱(当然是以和平方式)时,我提出了以下想法:

  1. 对于每个表,创建一个“包装器”视图,其中 (a) 包含该表的所有列;(b) 在某些情况下,有一些基于表的“真实”列的额外计算列。

    这种附加计算列的一个典型(尽管很简单)示例是从产品的正常价格和折扣得出的产品销售价格。

  2. 重新组织所有代码(T-SQL 和 VB/VBA 客户端代码),以便只有“包装器”视图直接引用表。

    因此,例如,即使应用程序或存储过程需要从表中插入/更新/删除记录,他们也会针对相应的“表包装器”视图执行此操作,而不是直接针对表。

所以,本质上这是关于通过视图将所有表与系统的其余部分隔离开来

这种方法似乎提供了很多好处,尤其是从可维护性的角度来看。例如:

  • 当要重命名表列时,无需一次重写所有受影响的客户端代码即可完成。

  • 实现派生属性更容易(比使用计算列更容易)。

  • 您可以有效地为列名设置别名。

显然,所有这些好处都必须付出一定的代价,但我不确定我是否看到了所有的陷阱。

有人在实践中尝试过这种方法吗?主要的陷阱是什么?

一个明显的缺点是维护“包装”视图与其对应表同步的成本(表中的新列也必须添加到视图中;从表中删除的列也必须从视图中删除;等等.)。但是这个价格对于使整个代码库更具弹性来说似乎很小而且很公平。

有谁知道其他更强大的缺点?

例如,使用所有这些“包装器”视图而不是表很可能会产生一些不利的性能影响,但这种影响是否足以让人担心呢?此外,在使用 ADODB 时,很容易得到一个不可更新的记录集,即使它仅基于几个连接的表;那么,“包装”视图是否会使事情变得更糟?等等等等...

任何评论(尤其是分享的真实经验)将不胜感激。

谢谢!


PS我踩到了以下讨论“包装器”视图概念的旧文章:

大视野神话

文章建议避免上述方法。但是......我真的没有在文章中看到任何反对这个想法的充分理由。恰恰相反,在创建视图的充分理由列表中,几乎每个项目都正是为什么为每个表创建“包装器”视图如此诱人的原因(尤其是在遗留系统中,作为重构过程的一部分) )。

这篇文章真的很旧(1999 年),所以无论当时的理由是什么,现在都可能不再是好的(反之亦然)。听到最近考虑甚至尝试过这个想法的人使用最新版本的 SQL Server 和 MS Access 会很有趣......

4

3 回答 3

11

在设计数据库时,我更喜欢以下内容:

  • 代码不能直接访问表(但可以从存储过程、视图和函数中访问)
  • 包含所有列的每个表的基本视图
  • 每个表的扩展视图,包括查找列(类型、状态等)
  • 所有更新的存储过程
  • 任何复杂查询的功能

这允许 DBA 直接使用表(添加列、清理内容、注入数据等)而不会干扰代码库,并且它将代码库与对表所做的任何更改(临时或其他)隔离开来

以这种方式做事可能会有性能损失,但到目前为止它们并不显着 - 绝缘层的好处已经多次挽救生命

于 2008-10-26T05:19:07.920 回答
4

您不会注意到单表视图的任何性能影响;在为使用这些视图的任何代码构建执行计划时,SQL Server 将使用基础表。我建议您对这些视图进行模式绑定,以避免在不更改视图的情况下意外更改基础表(想想可怜的下一个人。)

当要重命名表列时

根据我的经验,这种情况很少发生。添加列、删除列、更改索引和更改数据类型是您将运行的常用更改表脚本。

实现派生属性更容易(比使用计算列更容易)。

我会对此提出异议。将计算放入列定义和将其放入视图定义有什么区别?此外,您将看到将其移动到视图而不是计算列中的性能损失。唯一真正的优点是在视图中更改计算比更改表更容易(由于索引和数据页。)

您可以有效地为列名设置别名。

这才是拥有观点的真正原因;别名表和列,并组合多个表。在我过去的几份工作中,最佳实践是在我需要对数据进行非规范化的地方使用视图(如您已经指出的那样,查找等。)

像往常一样,对 DBA 问题最真实的回答是“这取决于” - 取决于您的情况、技能等。在您的情况下,重构“一切”无论如何都会破坏所有应用程序。如果您确实正确修复了基表,则不需要您尝试从视图中获取的间接信息,并且只会为将来的任何更改加倍您的架构维护。我会说跳过包装器视图,修复表和存储过程(它们已经提供了足够的信息隐藏),你会没事的。

于 2008-10-26T09:59:17.417 回答
1

我同意Steven 的评论——主要是因为您使用的是 Access。在重新设计此数据库时,关注 Access 的优缺点非常重要。我去过那里,使用 Access 前端/SQL Server 后端(尽管它不是 ADP 项目)。

我要补充一点,视图可以很好地确保数据不会在项目中的 Access 表单之外更改。缺点是所有更新都需要存储过程——如果您还没有这些,那么也必须创建它们。

于 2008-10-26T05:47:34.570 回答