您的数据库应用程序应该在存储过程中有多少?

时间:2009-06-09 20:48:37

标签: database-design architecture stored-procedures rdbms

我正在为数据库应用程序编写第二个接口,以解决原始接口的一些缺点。不幸的是,如果我创建新记录,则不会生成预期的审计跟踪记录。如果数据库设计将这些细节用于表触发器,那么肯定会很好,或者为在这些表中插入新记录等操作提供存储过程API。

一般来说,应用程序应该以这种方式设计吗?存储过程中应该有多少数据库应用程序?

8 个答案:

答案 0 :(得分:6)

我们的团队有一条规则 - 任何进出数据库的数据都必须通过存储过程。我们甚至已经对我们的数据访问组件构建限制以强制执行此操作。

对于其他事项,如簿记,审计跟踪等,我们也将它们放在存储过程中。触发器很方便,但我们发现,为了审计日志的目的,涉及更新的人员,内容和时间,并不是我们想要的所有数据都可用于触发器。我们曾经使用触发器的唯一一次是保持表中每条记录的完整更改历史记录,但即便如此,事后看来,它会导致维护问题,而且对我们来说更好。

答案 1 :(得分:5)

这完全取决于您的环境。这个问题的答案实际上不是编码问题,甚至是分析问题,而是商业决策。

如果您的数据库仅支持一个应用程序,并且与其紧密集成,那么出于灵活性的原因,最好将逻辑放在应用程序中。在这些情况下,将数据库简单地作为使用通用功能的普通数据存储库处理会使您失去灵活性并获得灵活性 - 包括供应商,实现,部署以及其他许多因素 - 以及'数据库用于数据'群众所做的许多纯粹论证都是示范性的真。

另一方面,如果您正在处理公司数据库(通常也可以通过多个访问路径来识别它),那么高度建议尽可能地降低安全性。至少应启用所有适当的约束,并且如果可能,仅应通过视图和过程访问数据。在这些情况下,应该忽略呜呜的程序员......

  1. 使用公司数据库,资产很有价值,无效数据或操作可能会对业务造成威胁。您主要关注的是保护业务,而不是为您的程序员提供方便的访问。
  2. 根据定义,此类数据库可由多个应用程序访问。您需要使用存储过程提供的抽象,以便在升级应用程序A并且您没有资源升级应用程序B时可以更改数据库。
  3. 类似地,在SP中而不是在应用程序代码中封装业务逻辑允许比在应用程序代码中嵌入此类逻辑更容易和可靠地在整个业务中实现对这种逻辑的更改。例如,如果计算必须在一个SP中更改而不是多个应用程序,那么如果税收计算更改,则工作更少,更稳健。这里的经验法则是业务规则应该在最接近数据的位置实现 - 因此,如果您有专家应用程序,那么该应用程序的逻辑可以在该应用程序中实现,但逻辑更广泛适用应该在SP中实施业务。
  4. 在您的情况下,您现在有多个应用程序访问同一个数据库,因此您应该将逻辑和审计功能从应用程序级别移动到数据库中。我自己通常会将审计功能放入数据库本身,因为如果我曾经被要求调查一些欺诈问题(并且已经发生了不止一次)我只是觉得我可以站起来并确定我的发现有更多信心比在应用层中还要少 - 这种警告的机会就少了。

    关于使用或不使用SP的宗教战争的编码人员通常只在一个环境或另一个环境中工作,因此他们将他们有限的经验推断到铸铁位置 - 这在上下文中确实是完全可辩护和正确的他们来自但却错过了大局。与往常一样,您应该根据自己喜欢的编码方法类型,决定业务/客户/用户的需求以及

答案 2 :(得分:3)

作为一般规则,我更喜欢在SP中保留尽可能多的数据;半通用数据访问层将处理触发请求,并将数据呈现给接口。

与SP“提高性能”的旧智慧实际上已不再相关*,但我发现使用此方法可以简化维护。

然而......我避免像瘟疫这样的触发器。它们很难维护,几乎不可能调试,并导致各种意外的副作用。

<小时/> *常见的看法是存储过程比ad-hoc sql查询表现更好。但是,这是错误的:

  

SQL Server 2000和SQL Server版本   7.0包含许多对语句处理的更改,这些更改扩展了许多   存储的性能优势   所有SQL语句的过程。 SQL   Server 2000和SQL Server 7.0没有   保存部分编译的计划   它们存储过程   创建。存储过程是   在执行时编译,像任何一样   其他Transact-SQL语句。 SQL   Server 2000和SQL Server 7.0保留   所有SQL语句的执行计划   在过程缓存中,不只是   存储过程执行计划。

     

- SqlServer's Books Online

答案 3 :(得分:3)

在具有来自应用程序的动态sql的数据库中更容易提交欺诈,因为权限是在表级别设置的。大多数欺诈都是由当前员工提供的,他们通常可以轻松访问服务器。心怀不满的员工也喜欢做破坏数据的事情。如果有任何财务数据,dba和一个备用dba,那么正好两个人应该能够访问生产数据库中的表。其他人应该只使用存储过程描述的任务,而不是其他任何东西。审计必须在数据库级别,否则基本上没有价值。如果我在不使用存储过程的应用程序中的应用程序级别进行审计(这两者通常一起运行),那么很容易让某人直接访问表,更改内容然后无法追踪。审计日志用于捕获对数据的更改,这些更改只能在数据更改的位置完全完成。

如果数据操作很复杂,那么存储过程也是性能调优的最佳方法。

使用procs的另一个原因是,如果对表的所有调用都封装在procs中,则在需要时重构数据库要容易得多。将小的更改上传到prod也要容易得多。

答案 4 :(得分:2)

一切都应该在适当的位置。

数据库必须保护其周边。它不能假设只允许连接它的人是受信任且经过测试的应用程序。

迟早有人会使用有缺陷的应用程序或有缺陷的客户端库连接到它(Oracle有一些允许用户创建无效日期的客户端)。或者他们将与报表编写者或Access或Excel连接。

我的首选不是允许直接访问表,而是仅允许访问视图,SP等,因此在那里管理基于角色的权限,并且形成的接口契约与为类定义接口的方式非常相似或应用程序层的服务。这并不意味着所有/多应用程序逻辑都在存储过程中,但它确实意味着数据库强制执行某些规则 - 通常是基本的规则 - 如引用完整性 - 以便应用程序 CAN 对如何做出一些假设该数据库过去曾安全使用过以前的版本。

在Tech Ed 2009上有一个很好的小组讨论,you can watch here

答案 5 :(得分:1)

恕我直言你应该为任何专用于处理数据的逻辑创建SP,并且可以作为应用程序和数据库之间的良好抽象。一个很好的例子是密码的应用内哈希。我总是创建一个SP来创建记录并为我隐藏密码....

因为哈希密码实际上是数据库域。我还创建了一个SP来检查密码字符串是否是相同的哈希值(是的,这是传输到数据库,但我相信我的数据库和网络)。

忘记弱势的例子:当你可以分开关注而不损害你的系统的设计和完整性时......制作抽象并做到这一点!

金融行业使用很多SP在数据库上创建有效API 来处理肮脏的财务操作,因为他们可以在外部内置审计应用程序在存储过程中。

在一个典型的设计中,当您想到时,RDBMS端和应用程序端应该是非常明显的...... '应用程序是否需要对数据执行此操作,是否关心?'< /强>

答案 6 :(得分:1)

不同的哲学有不同的答案,但这是我的

  1. 数据密集型计算 - 特别是在数据库外部进行的任何非常昂贵的事情。

  2. 共享代码。我上一次使用关系数据库的工作是连接到数据库函数库。 Java代码对此连接一无所知。为了避免重复,与库通信和Java使用的代码所需的任何功能都是存储过程。

  3. 另一个问题是确保对困难或关键代码进行测试。这并不意味着它不能成为一个存储过程,只是至少在开始时可以更容易地将它写入测试更容易的地方。

    显然,如果函数需要与外部服务通信(数据库无法轻松访问),您可能不希望将其作为存储过程。

答案 7 :(得分:1)

以下是另一种观点:

数据库用于持久数据。

您的申请是为了处理。所有逻辑,所有代码,所有决策,所有计算,所有参照完整性,一切都应该在您的应用程序中。

如果你有一个只有数据的简单数据库,它会让生活变得非常简单。

从长远来看,很多人发现他们的存储过程和触发器造成了一个难以(或不可能)维护的混乱局面。通过将数据库用作快速,大型,易于备份的数据存储库,可以轻松防止这种情况。索引和视图以及数据库的适当部分。

其他一切都不属于那里。

Folks解除了“问题”,如下所示。

  1. 数据库是“中心”。不知何故,应用程序服务器不是核心。我不明白。如果要集中处理,请使用应用程序服务器。如果您需要大量复杂的集中处理,请使用ESB。

  2. 某些处理“更接近数据库”。有很多不好的例子。好的例子通常与代理键分配有关。我更喜欢使用ORM层(iBatis或SQLAlchemy或其他)来执行此操作。无需编写或维护存储过程即可获得相同的效果。

  3. 某些处理需要审核。实际上,所有处理都需要审核。将业务域对象与ORM一起使用,并在您的应用程序中进行审计处理。

    基于RDBMS的内置审计很好。您使用存储过程编写的任何审计都不会那么好。解决方案 - 在应用程序中使用日志记录,以及数据库引擎的内置审计功能。避免使用触发器和SP。

  4. 存储过程更快。这是不真实的。良好的交易设计使事情更快。存储过程会对您的体系结构施加一些限制,这有时会迫使您创建小而整洁的事务。尝试用Java编写相同的小型,重点突出的事务,你会发现PL / SQL实际上并不快。

  5. 您可以在没有存储过程的情况下生活。从长远来看,你会发现专注交易的设计规则比程序本身更有价值。

    示例

    “如果我创建新记录,则不会生成预期的审计跟踪记录”

    如果您有适当的Business Domain类定义来创建记录,它还会在您的应用程序中为您创建审核记录。