将数据库逻辑放在应用程序中而不是触发器,存储过程,约束等

时间:2010-07-31 15:17:25

标签: mysql ruby-on-rails database postgresql

我正在使用Rails,它不支持数据库特定的操作,如触发器,存储过程和各种约束(不是全部)。

我想知道是否应该将数据库逻辑放在应用程序本身中。

因为那时你可以创建比数据库提供的更复杂的逻辑,它也是数据库独立的(我可以从mysql移动到postgresql,反之亦然),如果你把这些东西放在数据库中就不会这样。

这是正确的方法吗?

由于

9 个答案:

答案 0 :(得分:14)

(注意:这是一篇以Postgres为中心的帖子。我有几年的MySQL经验,还有一些Postgres和Oracle。我更喜欢Postgres一个国家里程,但这不是这篇文章的重点。)

这真是一个关于两种思想流派的问题:数据库应该只是一个数据存储还是应该包含应用程序逻辑?两者都有。

恕我直言,在几个DB(特别是Postgres)在DB本身中获得了一些非常非常好的过程语言之前,答案过去简单得多了。在此之前,将所有可能的逻辑放在应用程序中是有意义的,因为在基本SQL中完成某些操作必须相当笨拙。

另一个答案的Dave Markle对触发器提出了一个很好的观点,它们往往对开发人员来说是“神奇的”。在途中改变输入可能非常混乱。如果我说UPDATE foo set X=3;但我会检查foox真的是4,因为有些触发器拦截了它,可能会让人感到困惑。像戴夫一样,我倾向于推广审计功能等的触发器。触发器的另一个问题是性能,他们可以从良好的批处理操作中榨取生命。

存储过程 - 我更加重视。开发人员明确地调用它们并且它们被命名,因此他不应该将它们视为黑盒子。良好的存储过程可以通过减少需要“通过线路发送”的行数来大大提高速度。对于像Postgres这样具有强大PL语言的数据库来说,SP中没有任何东西是不可能的(这并不意味着它应该被完成,但可以)。请查看SimplyCity,了解存储过程如何成为您的朋友。此外,您可以在应用程序代码和PL / python,PL / Perl或PL / Php,PL / Ruby或PL / Java之间共享应用程序逻辑类。我相信Oracle可以用Java做类似的事情 - 这不是我目前正在为Oracle工作的公司所做的事情。

如果您计划保持数据库不可知,那么您将牺牲很多功能,速度和时间。 ORM可以使这更容易,但最终在大多数数据库引擎中存在根本区别,这些引擎无法完全抽象出来。

总的来说,您需要测试,测试,测试(使用真实数据)并做出最适合您应用的决策。它通常是性能,未来维护,成本和您必须使用的资源之间的平衡行为。 经常(不是每次),将逻辑移出数据库并进入应用程序会大大降低应用程序的性能。

即使您没有决定将应用程序逻辑放入数据库 - 请花时间真正了解您选择的数据库。从长远来看,它将使您成为一个更好的应用程序开发人员。

答案 1 :(得分:6)

我会给出一个可能与其他人会说的相反的答案。

数据库逻辑属于您可能实现的数据,并且这意味着在数据库中。做其他事情充其量只会要求你在不同的应用程序中重复自己,并且有一个很大的更新问题。在最坏的情况下(这很可能),您将在不同的应用程序中实现不一致的数据库逻辑。

你需要分离出什么是“数据库逻辑”和什么是“应用程序逻辑”。我的正常例子是通过“FullName”为客户定义组织的含义。想象一下,您在应用程序中编写了将名字和姓氏组合成全名字段的代码。稍后,您将添加中间首字母(或决定包含已存在的中间初始列)作为全名的一部分。

如果您的全名逻辑在视图或存储过程中实现,则只需进行一次更改即可跨所有应用程序(包括您没有源代码的第三方应用程序)强制执行新定义。 / p>

在诸如Ruby之类的情况下,问题有所缓解,其中所有数据访问都是通过共享的ORM层完成的,您可以在其中放置将使用相同语言编写的所有应用程序使用的逻辑。然而,在我的情况下,我很少在只有一种语言或产品用于公司数据库编程的情况下工作。

答案 2 :(得分:5)

如果您已经在使用Ruby on Rails,那么您已经致力于使用固定意见的软件。无论是对还是错,Rails对此问题的看法是逻辑在Rails应用程序中。它甚至可以通过ActiveRecord及其关联强制执行引用完整性,尽管如果您希望通过向表添加约束来在数据库中强制执行此操作。很多Rails开发人员都不会因为无知或选择而烦恼。

  • 当你开始偏离其意见和惯例时,Rails提供的生产力提升趋于减少
  • 如果你正在编写那种操作大量数据的应用程序,并且可以从利用特定的RDBMS功能中受益,那么无论如何这都不适合Rails,因为它已针对创建新的CRUD Web应用程序进行了优化

答案 3 :(得分:4)

  

因为那时你可以创建比数据库提供的更复杂的逻辑,它也是数据库独立的(我可以从mysql移动到postgresql,反之亦然),如果你把这些东西放在数据库中就不会这样。

逻辑依赖于数据库 - 例如,MySQL没有递归查询支持,也没有分析函数。 PostgreSQL最近才获得分析 - 自2005年以来,SQL Server一直都有这样的分析。 Oracle自9i以来。

应用程序中的数据库逻辑ltypically意味着应用程序和数据库之间的更多行程 - 这是您永远无法收回的时间/性能。数据库跳闸是昂贵的,并保持尽可能少 - 这就是为什么存储过程&函数是高度可扩展,高性能持久层的最佳工具。

ORM长期以来因为不复杂的查询而闻名,我很高兴看到他们已经发展到支持使用存储过程/等。 ...这完全违背了使用ORM的目的 - 现在你又回到了为了性能而编写特定于数据库的代码。这就像用正则表达式解决问题的笑话 - 现在你有两个问题......

最后,数据库 - 表格和数据类型 - 也没有移植到其他供应商认为有转换工具包。即使数据库中的更改也很痛苦,这就是数据库设计/建模开发在敏捷/交互式开发过程中不能很好地工作的原因。

结论

如果您拥有使用小型数据集的超级简单应用程序,那么应用程序中的数据库逻辑非常有用。但是,在学习数据库开发的过程中,它将获得成功 - 您的客户将从更具可扩展性,更快速的应用程序中受益。

答案 4 :(得分:4)

我自己坚定地参加了“应用逻辑”阵营。

对我来说,最重要的问题与在应用程序增长时扩展持久层有关。通过严重依赖数据库来实现您的逻辑,您需要将应用程序签名以进行数据库分片或复制,作为您的持久层的扩展解决方案。我发现在业务对象层有大量的分布式缓存解决方案,取得了更大的成功。

次要表现是实施的透明度。现代面向对象设计在将数据和业务逻辑结合在一起有很多好处,但是当你依赖外部和隐藏的逻辑层时,它在很大程度上会陷入混乱。

答案 5 :(得分:1)

一般来说,是的,主要是出于你刚才提到的原因。

触发器特别糟糕,因为开发人员对执行操作时幕后实际发生的事情非常不透明。我倾向于将触发器的使用限制在审计功能或对保护系统数据完整性非常重要的功能。我几乎完全避免使用触发器来应用逻辑。

与存储过程相同。在ORM如此普及的这个时代,我使用存储过程进行大型的,基于集合的数据修改,当使用诸如Rails之类的ORM时,其性能将会出乎意料地糟糕,这需要您从数据库中读取数据并封送它完成处理后返回数据库层。

答案 6 :(得分:1)

我认为RDBMS应该是愚蠢和灵活的,严格用于持久性,不同的企业应用程序应该通过SOA技术进行通信。

我以标准化,灵活的方式创建数据结构,通常只使用数据类型和参照完整性约束。数据由应用程序(“母亲”)管理,该应用程序实现内聚域所需的任何规则。如果不同的(或第三方)应用需要访问这些数据,它们不应该破坏母亲并直接进入数据存储,而是使用SOA技术与她沟通,要求她采取行动并对结果做出回应(她返回给他们的包括失败。

我这样想。如果我想访问我公司的电子邮件数据,我不会直接访问它们驻留在磁盘上的位置。这将是痛苦的,因为我必须先了解数据结构才能做任何事情。相反,我通过SOA(WebDAV,CDO,LDAP等)技术与我的电子邮件服务器应用程序(在我的情况下是Exchange Server)进行通信。此应用程序提供了一个抽象层来查询电子邮件,日历或联系人数据,发送电子邮件或创建联系人或约会,或管理日历等。

如果这些其他应用程序(由您创建)与母版应用程序(也是由您创建)没有根本的不同,那么您可能拥有太多的一次性应用程序,并且应该将这些应用程序的组合开发为常见应用程序直观的企业系统。然后,这些应用程序中的每个应用程序(例如,我称之为模块)都可以直接访问数据,利用通用数据访问层实现在复合应用程序中集中定义的相同内聚规则。当然,复合应用程序应该通过SOA技术提供对数据的访问,这样真正完全不同的应用程序就可以与她进行通信。

答案 7 :(得分:1)

有数据逻辑,有应用逻辑。数据库必须知道有关数据逻辑的一切,关于应用程序逻辑的应用程序。数据逻辑可以存储在数据库中的存储过程,视图,规则等中.Oracle,PostgreSQL,SQL Server等具有非常强大的工具来支持它。

许多应用程序可以使用相同的数据库和相同的数据,您必须确保数据是正确的。每个应用程序(使用任何语言)都可以使用此数据执行不同的操作,这取决于应用程序。在应用程序中构建数据库逻辑,就像重新发明轮子并提出麻烦一样。 RDBMS有大约40年的开发历史,你不会在几周或几个月内获得更好的结果。

对于PostgreSQL,看一下不同的PL:PL / pgSQL很好,PL / perl和PL / ruby​​可能对perl和ruby开发者来说更​​有趣。

答案 8 :(得分:0)

我研究了触发器应该在哪里(应用程序端还是数据库端)。设计决策都各有利弊。

 Database Trigger
   pros:
     - Simplifies application logic
     - Better performance
   cons:
     - Maintaince is harder
     - Database dependency
     - Batch operation performance problems
     - If you don't have access to database for prod envoriment, It can be harder to manage


 Application Logic:
   pros:
     - Maintaince can be done in one place. It is good thing.
     - Database independent if you use ORM tools or frameworks.
   cons:
     - Performance may be problem
     - Add some complexity to the application logic

以下是关于该主题的观点:

”“如果您只有一个对数据库(或至少对此处的相关表)具有写权限的应用程序,并且您的CRUD操作位于该应用程序的一处,则通常无需使用触发器当您不知道将来谁和什么进程/应用程序将访问您的数据库时,并且您希望将很多一致性规则保存在一个地方(主要是在数据库中)时,触发器是一件好事。 “

enter link description here