为什么被忽略的数据库function,而是在中间层重新创build?

除了“数据库独立性”之外,现在大多数IT项目似乎都忽略了现代数据库引擎(如Oracle 11g和SQL Server 2008)中存在的丰富function,这是什么原因?

或者,从赫尔辛基宣言的博客中借用这样的话:

在过去的二十年里,我们观察到DBMS内部可用的function(特性)呈指数级增长。 这些function使我们能够构build数据库应用程序 这就是我们在九十年代兴盛的时候开始做的事情。

但是,在新千年来临之际,发生了一些事情。 而神秘的是DBMS在数据库应用程序项目中扮演的angular色却微不足道。 (…)截至新千年,我们将所有的应用程序逻辑从DBMS推到中间层服务器。 在DBMS之外实现的function已经爆炸,function丰富的DBMS几乎不用于行存储。

我们正在谈论像这样的东西

  • 用作数据API的存储过程(用于安全并避免过多的networkingstream量)
  • 物化视图
  • 取而代之的是触发器
  • 分层查询(通过连接)
  • 地理(空间数据types)
  • 分析(铅,滞后,汇总,立方体等)
  • 虚拟专用数据库(VPD)
  • 数据库级审计
  • 闪回查询
  • 数据库中的XML生成和XSL转换
  • 来自数据库的HTTP标注
  • 后台作业调度程序

为什么这些function不被使用? 为什么大多数Java,.NET和PHP开发人员坚持使用“SELECT * FROM mytable”方法?

由于存储过程:

  • 添加另一种开发语言,增加复杂性和潜在的冗余代码(用两种语言编写的逻辑);
  • 一般比PHP,C#,Java,Python等都有更差的工具,监控和debuggingfunction;
  • 通常不如大多数中间层语言的能力;
  • 只有在大容量数据转换(避免服务器往返)的情况下才具有优势,这往往只是实际使用的最低限度。

这就是说,这是一个在C#ASP.NET应用程序中的常用方法。

正如Jeff Atwood所说, 存储过程是数据库的汇编语言,除非需要,否则人们不会倾向于使用汇编语言编写代码。

我经常使用物化视图,有时在Oracle中使用CONNECT BY,这两者我都不相信在MySQL中存在。

我不倾向于在数据库中使用XML / XSLT,因为这意味着我正在使用XML和XSLT。

至于地理或空间数据结构,原因可能是他们很难“拾起”。 这是一个相当专业的领域。 我已经阅读了关于空间数据结构的MySQL手册,我相信对于拥有广泛的GIS经验的人来说,这是有意义的,但是对于我和我有限的需求(这往往是围绕着标记一个点的纬度/经度)看起来值得花时间去投资。

另一个问题是,如果超越ANSI SQL(很多),那么你只是将自己绑定到特定的数据库供应商,并可能与特定的版本。 因此,您经常会发现应用程序开发人员倾向于将数据库视为最低公有标准,这意味着将其视为关系数据的倾倒场。

因为开发人员不了解SQL。 他们依赖于像Hibernate这样的工具生成的DDL和DML以及像JPA注释这样的语言级别的构造。 开发人员并不关心这些效率是否非常低,因为它们被正常的日志级别所隐藏,因为DBA不是开发团队的一部分。

这就是为什么我喜欢工具iBATIS 。 他们让你编写和理解SQL,包括DBMS特有的function。

我想有一个原因是供应商lockin的恐惧。

这并不经常说,但是使用供应商特定function的好处需要与成本进行权衡。 主要是为了支持每个数据库而必须重写依赖于供应商特定function的部分的成本。 当供应商提供更好的方法时,如果您以通用的方式实现某些东西,那么也会有性能成本。

我将举出这个例子:一旦人们意识到Analysis Services,Reporting Services等能够为您的应用程序做的所有事情,就会发现SQL Server的“locking”更加可以接受。 对于主要的商业数据库系统来说,不仅仅需要考虑SQL数据库引擎。

“为什么数据库function被忽略”。

因为很多所谓的开发人员对数据pipe理完全一无所知,更糟糕的是,他们也完全不知道自己的无知。 “不熟练和不知道”,为此敲响了一个钟声。

如果你的软件运行在你的客户端的硬件上,那么对数据库的任何改变(新的存储过程,更新的视图等)都需要数据库pipe理员权限。 这对客户来说几乎总是一个问题。 涉及数据库组会使您需要执行的任何更新复杂化。 这里提出了很多很好的理由,但这是我唯一需要避免将代码放在数据库中的代码,比如鼠疫。

我想有一个原因是供应商lockin的恐惧。 这些DBMSfunction并不是标准化的 – 例如,存储过程非常具有数据库特定性,如果你使用存储过程(而不是通过中间层公开的Web服务)来实现东西,那么你将永远被困在DBMS中(也就是说,除非你愿意花时间/金钱在另一个DBMS中重新实现,如果你想改变DBMS的话)。

MySQL的。

当Web应用程序在20世纪90年代末和21世纪初发生爆炸时,MySQL的版本是3.3或4.0,并且不支持超过简单SELECT的任何东西。 但是,它是免费的,并且与大多数Linux发行版一起安装。 结果,一代程序员没有学习数据库,也不知道如何使用它们。

即使现在MySQL已经在5.1了,并且支持商业系统的大部分function,当一个新的LAMP项目被启动时,同样糟糕的旧博客和文章也被用作模板,MySQL被部署了MyISAM表和3.3时代的function。

由于和Haskell相同的原因,SQL失败了。 决定语言成功的标准并不是纯粹的,不是电脑解释的简易性,但是维护写在其中的程序是多么困难。

即使是最简单的语言,凡人也会失败。 也许十分之一的人拥有使用像C#这样简单的语言的技能。 但在这10%的人中,只有10%或1%的人能够有效地使用像SQL或Haskell这样的语言。

现在,作为一种语言,SQL是不完整的,因为只有SQL可以做很less的事情。 你将永远需要另一种语言。 这对SQL有什么作用? 开发人员将理解ACID相对于平面文件存储的优势,但除此之外,数据库真的没有什么可以提供的。

第二个问题是,SQL实际上与源代码版本不兼容。 SQL看起来确实是build立在第一次正确的时候。 所以,这不仅不适合开发人员,而且对于开发过程来说也不太适合。

与DBMS相比,修复/重新部署中间层更容易。

这可能取决于你的架构,但这是我们的理由。 再加上我们有一个比较忙的DBA(可能)比我们的开发人员还要多。 所有的开发人员都知道SQL,他们中的一些人熟练掌握过程语言。 如果出现了一个非常棘手的生产问题,那么开发人员在数据库的中间层工作会更容易,更快,无论这种架构是否会更好。

我遇到了很多人,他们并不知道这些特性是存在的 – 他们在MySQL的早期就开始削减他们的function,他们从来没有真正使用过其他的东西,他们也没有跟上甚至在MySQL中新的存储表的进步。 或者他们在学校学过数据库,他们从来没有回过头去看到他们错过的所有东西。

他们学习的只是最低限度的SQL,并没有意识到不同RDBMS提供的所有不同的扩展。

在一个项目中,我很想拥有物化视图,但是我正在使用Postgres。 我很喜欢为另一个项目使用空间数据types,但是我将不得不做一些破解,或者改变数据库来处理mySQL的空间数据types。 我甚至不得不弄清楚如何禁用Oracle的事务一致性来处理OLTP上长时间运行的查询,这在MySQL中是没有问题的。

我通常可以针对某个特定的问题编写数据库的缺点,但是其中的一部分问题是select正确的工具 – 在当前的项目中,我们浪费了数个人工月份来处理数据复制,因为我们使用Postgres,他们决定在Slony-1之前,他们真正知道我们将要复制的所有东西。

…我认为这个问题就像'为什么不用更多的人在语言y中使用特征x ' – 如果他们不是语言y的专家,他们可能不知道特征x存在。

(不要把它当作获得DBAauthentication的支持……我知道一些Oracle数据库pipe理员不能从湿麻袋中编程,我已经在8i的时间内完成了所有课程,但是拒绝接受testing,因为我不想被这个小组所迷惑)

我认为,其余的最大的原因是,当多个应用程序共享相同的数据时,关系数据库系统变得更加重要。 Codd的着名论文题为“大型共享数据库的数据关系模型”(重点介绍)。

人们倾向于认为他们现在写的应用程序总是由他们的团队来控制; 并始终满足对应用程序生成的数据感兴趣的人们的所有需求。 如果出现新的需求,可以通过向现有应用程序添加新function来满足,而不是创build新的应用程序。

但在很多情况下(当然不是全部,每一种情况都不一样),长期来看,这种发展模式并不能很好地发挥作用。 随着应用程序生成的数据越来越多,对业务变得越来越重要,不同的人会对如何使用这些数据产生兴趣。 当发生这种情况时,如果你没有关系数据库pipe理系统,那么你将面临巨大的挑战。

可扩展性。 您给数据库服务器的工作越多,就会变成一个瓶颈。 它具有更大的可扩展性,使整个服务器负载均衡的应用程序服务器处理数据,并将数据库用作持久性存储。

在许多情况下,企业的政治(“我们不允许访问SQL Server,所以我们可以安装像Access这样的function较差的DBMS来处理数百万行,并将其与另一个表中的数百万行结合在一起,并让这个导入自动化..“),甚至可能发生的技术政治(”我知道Access可以处理这些数据量,即使它不能把MDB分成几个MDB并引用它们……“)

啊。 公司政治和技术政治乃至无知使我无法使用许多function。

另一个例子 – 我没有理由不使用存储过程在SQL Server是DBMS的100%微软商店。 但是,因为最终要拥有这个解决scheme的IT人员对于SP来说是“光明的”,所以我不得不采取其他措施。 我的意思是,有一个很好的例子说明为什么有些“特色”被他们在店里忽略了。

我知道另一家商店仍然使用DOS Foxpro 2,因为他们唯一的IT人员用这种方式编写了现有的系统,这就是所有新的东西将被开发的方式。 为什么? 我们不能跟着时代前进吗? 那里的许多营销人员都有几个DOS提示符,Foxpro的“工作”在其中运行,产生了我见过的最丑陋的报告。 但它的作品 – 我会给他们的。 它的工作原理 – 他们在主桌上有1200万行,还有50多个与主桌“join”的桌子(显然不是全部都是50桌子),而是人类…… 1991年过去了! 他们甚至不想讨论你在问题中提供的子弹列表中的一个项目。

像这样的东西是我猜的原因。

我想说的最大的原因是大多数人不知道他们。 一旦有人找出了问题的解决scheme,那么这个解决scheme就成为了类似问题的默认解决scheme。 SELECT * FROM表已经为很多人工作了很长时间,所以他们不用费力去寻找解决旧问题的新方法。

另一个原因是,有时在代码中写入比使用数据库要容易得多。 它是一样的想法,滚动自己与购买现成的组件。 使用预先编写的function可以多次解决您的问题,但是每过一段时间,您都需要做一些超出预先编写的组件function的function。

很好的问题,好的讨论。

另一种说法是“为什么不反对数据库? 这是硬币的另一面。 数据库仍然是一个恼人的抽象,仍然泄漏到每个应用程序的方式,但它们与现代应用程序的OO逻辑不兼容。

在ActiveRecord,Hibernate和其他中间件中隐藏和复制数据库的function确实是一个奇怪的事态。 但这就是在断裂点(“对象 – 关系阻抗不匹配”)中发生的情况。 我们是否会过渡到类似于我们的OO应用程序的数据库技术(例如,对象DB)?

答案是“不是很长时间”,与此同时,期望DB在许多情况下被忽略和压扁,只用于行存储,因为中间层在function上增长以弥补差距。

另一个问题是“如果中间层能做到这一点,我为什么要在数据库中做这件事?” 中层人员一直都是熟悉的,并且在速度和function上都处于领先地位。 再次,我们使用中间层来避免OO-RDMS不匹配。

推进基督教所说的可扩展性。

简而言之,RDBM正在被更多地用作纯粹的数据存储,而逻辑已经被迁移到了应用服务器中。 AS的额外层为开发人员提供了比使用RDBMS作为应用程序服务器更大的灵活性。

在Fat Apps和Client Server的传统日子里,DB和Application Server基本上是一回事。 您将应用程序逻辑embedded到胖客户端代码中,或者将其推回到RDBMS中。 但是那个时候,沟通的主要forms是SQL直接到数据库。

现在,其他应用程序协议更常见(CORBA,DCOM,远程EJB,以及现在越来越多的通过HTTP使用XML / JSON / HTTP-RPC格式的协议)。 大多数数据库不直接响应这些协议,因此应用程序层被插入以拦截这些调用,并且该层调用数据库。

但是据我们所知,我们现在获得更多的灵活性,把逻辑放在这个层上。 更宽的工具select,更高的caching或故障转移的灵活性,甚至数据库技术(RDMBS,OODBMS,像CouchDB这样的文档存储)。 尽pipe增加了复杂性,第三层的“新”层比其引入的复杂性增加了更多的灵活性和能力。

当您的应用程序层在存储过程之上是一个非常薄的单板时,可以质疑为什么它甚至在那里。

利用数据库及其所有function是一种有效的应用策略,即使在今天。 SQL Server,Oracle等,都是非常强大的软件。

即使如此,第三层对于增加现代系统的灵活性也是非常有帮助的。

对我而言,原因不仅在于我的应用程序是数据库不可知的,而且最好的数据库performance了基本的CRUDfunction。 是的,数据库是高度优化的,可能能够做一个HTTP标注,但为什么你会这样做呢? Web服务/ Web应用程序针对HTTP调用进行了优化,而不是数据库。 就像应用程序不是直接连接到数据文件并检索数据一样。 可以这样做吗? 是的,但是为什么? 这不是你的应用程序EXCELLS在。

我个人觉得,你提到的一切,存储过程的外面属于应用程序。 如果你知道你的架构是X,那么利用X的特性,在适当的时候手工加载到数据库服务器等等。如果它可能是X或Y(或Z),那么你的应用程序应该是不可知的,除非你是试图通过确保您可能不得不重构应用程序来创build工作安全:)。 我觉得有点懒惰,加上舒适性可能与它有关。 我知道我宁愿在C#中做,而不是SQL。 。 。 我的C#技能只是更好。

首先:任何使用ORM的开发人员都是天真的,如果他/她认为使用ORM否定必须具有SQL技能。 生成SQL的大多数ORM根据构build对象查询的方式而改变发出的SQL。 开发人员需要分析SQL以查看是否应该更改任何对象查询。

简短的回答:很多这些function对于开发OO是不实际的。 我知道DBA不喜欢听到这个,但事实就是这样。 这些function对于边缘情况非常有用,而且大多数好的ORM(例如N / Hibernate)允许您为这些边缘情况提供SQL。

当涉及到主要委托给CRUD时:

长的回答:我认为RDBMS世界正在经历成熟的痛苦,并且正在发现它在世界上的位置。 事实:OOP比RDBMS旧。 OOP正在摆脱它的痛苦和成熟。 我认为SQL作为一种语言是非常成熟的,但是关于RDBMS应该处理什么的想法正在得到解决。 RDBMS是大多数Web应用程序的业务逻辑持有者,直到Java和C#出现为止。 我想我们现在才开始感觉到这个改正。

这就是说,我不认为任何ORMdevise师会告诉你,提供给RDBMS的sql语句的质量并不重要。

说到非CRUD,我在这里没有答案。 我所知道的大多数商店仍然使用数据库来进行ETL / etc …

没有足够的开发人员知道所有这些function,这些function对于一个普通的“中间层”程序员来说,在DB或中间层实现相同的逻辑时,真的会有所不同。 也许真正深入了解这些function的单身人士是数据库pipe理员。 那些关注于其他问题而不是发展。 除了DBA外,还有更多的“正常”开发者。 因此,为您的团队find合适的人员将是非常困难和昂贵的。

还有一点是,你通常只会收集关于一个数据库系统的深入知识,而不是全部。 因此,您可以拥有SQL Server专家或Oracle专家,但不能同时拥有这两者。 这导致(在一定程度上)狭窄的应用领域,高专业化。 那么,这样的应用程序的市场并不那么大,即使它在那里。

我认为这是由于大多数RDBM用户对供应商的locking和缺乏知识的结合。 SQL是一种编程语言,掌握从SQL和SQL调用的语言,而不是掌握其中的一种语言更为困难,特别是SQL是一种特别独特的语言。

我认为解决scheme是将数据库function抽象为一个实用程序类,并将该类的所有权交给了一些知道他们在用SQL来做什么的用户。 这最大限度地降低了供应商locking的风险(如果您切换供应商,唯一被重写的是类)。 这也给了不是SQL专家的开发人员一个抽象的接口,所以他们不必直接处理数据库。

我已经看到,利用增加的数据库function的一个问题是缩放。 扩展数据库负载与Web /应用程序服务器负载似乎是一个更困难的提议。

您的select是有限的,扩大与更大的硬件更快(有时更高的许可成本),或复杂,扩大与只读副本等。

如果有性能问题,我希望他们在Web服务器应用程序级别。 至less我的select之一是添加另一个Web服务器并分发负载。

我不争论数据库级别的代码,以尽量减lessWeb服务器和数据库服务器之间发送的networking通信量(logging)。 我正在反对其他function,例如。 在数据库级进行广泛的业务逻辑处理。

有几篇文章指出,在应用程序层比在db层更便宜。

另一个考虑是访问多个数据存储的复合应用程序。 在应用层中编写和维护平台不可知的查询语言比在db层中分离特定于平台的查询要容易得多。

因为用宿主语言编写面向对象的软件,用原生的宿主语言对象编写程序软件。

我一直致力于销售给许多客户端并在客户端硬件上运行的系统。 这导致:

  • 您不知道客户端将运行的数据库软件的版本。
  • 由于许可证费用或IT政策,客户可能不愿意在需要时更新数据库软件。
  • 即使像物化视图这样的基本function只是在数据库软件的某些“版本”中,较小的客户通常不愿意为数据库的高端版本付费。
  • 您的销售人员迟早会同意您的软件与其他供应商的RDBMS一起使用。
  • select在中间层写逻辑一次,还是至less在数据库中使用PL-SQL和TSQL是一个简单的select!
  • 对数据库的任何更改(新的存储过程,更新的视图等)将需要DBpipe理员权限; 在某些客户网站上这可能会更困难,然后只是更新您的软件。
  • 编写脚本来更新数据库总是比安装应用程序的dll的新版本更难。 (现在大多数构build系统都将MSI文件作为每个构build的一部分输出)
  • unit testing代码很难在数据库中,然后是中间层。
  • debugging存储过程比C#更难。
  • 仅仅因为它在你的数据库上工作并不意味着它会在客户的数据库上工作,RDBMS有太多的交换机会改变它们的工作方式 – 客户总是倾向于以不同的方式设置它们。

因此,考虑到上述情况,使用数据库function所带来的收益必须很大才能值得长期的痛苦。