MySQL存储过程使用它们或不使用它们

我们正处于一个新项目的开始,我们真的想知道是否应该在MySQL中使用存储过程。

我们只会使用存储过程来插入和更新业务模型实体。 有几个表格代表一个模型实体,我们会在这些存储过程的插入/更新中抽象出它。

另一方面,我们可以从Model层调用插入和更新,但不能在MySQL中调用,而是在PHP中调用。

根据你的经验, 哪一个是最好的select? 两种方法的优点和缺点。 在高性能方面哪个是最快的?

PS:这是一个大部分阅读和高性能的Web项目是最重要的必要条件。

与实际的编程语言代码不同,它们:

  • 不是可移植的(每个数据库都有自己的PL / SQL版本,有时候同一个数据库的不同版本是不兼容的 – 我已经看到了!)
  • 不容易testing – 你需要一个真正的 (开发)数据库实例来testing它们,因此作为构build的一部分unit testing他们的代码几乎是不可能的
  • 不容易更新/可释放 – 你必须删除/创build它们,即修改生产数据库释放他们
  • 没有图书馆的支持(为什么在别人的时候写代码)
  • 不容易与其他技术集成(尝试从他们的Web服务调用)
  • 他们使用的语言与Fortran一样原始,因此不够高效,难以获得有用的编码,所以很难expression业务逻辑,尽pipe通常这是他们的主要目的
  • 不要提供debugging/追踪/消息logging等(有些dbs可能支持这个 – 虽然我还没有看到)
  • 缺乏一个体面的IDE来帮助语法和链接到其他现有的程序(例如像Eclipse一样的Java)
  • 熟练编码的人比应用程序编码人员更稀有,更贵
  • 他们的“高性能”是一个神话,因为他们在数据库服务器上执行它们通常会增加数据库服务器负载,所以使用它们通常会降低您的最大事务吞吐量
  • 无法高效地共享常量(通常通过创build表并从您的过程中进行查询来解决 – 效率非常低)
  • 等等

如果你有一个非常特定于数据库的操作(例如一个事务内操作来维护数据库的完整性),或者保持你的过程非常primefaces和简单,那么你可能会考虑它们。

build议在预先指定“高性能”时谨慎。 它往往导致糟糕的select,牺牲好的devise,它会咬你很多,比你想象的。

使用存储过程自己的危险(来自曾经在那里,永远不想回去的人)。 我的build议是避免他们像瘟疫一样。

与编程代码不同,它们:

  • 渲染SQL注入攻击几乎是不可能的(除非你是
    构build和执行dynamic
    你的程序中的SQL)
  • 作为标注的一部分,需要通过IPC发送less得多的数据
  • 使数据库能够更好地caching计划和结果集(由于其内部caching结构,这对MySQL来说并不那么有效)
  • 很容易被单独testing(即不作为JUnittesting的一部分)
  • 是可移植的,因为它们允许你使用数据库特有的特性,抽象出一个过程名称(在代码中你被genericsSQLtypes的东西所困)
  • 几乎从不比从代码调用的SQL慢

但是,正如波希米亚所说,也有很多缺点(这只是提供了另一种视angular)。 在决定什么是最适合你的之前,你必须先进行基准testing。

至于性能方面,他们有潜力在未来的MySQL版本(在SQL Server或Oracle下,它们是一个真正的享受!)真正的performance。 然而,其余的……他们完全打破了竞争。 我会总结一下:

  • 安全性:你可以只给你的应用程序执行权利,一切都很好。 您的SP将插入更新select…,没有任何可能的泄漏。 这意味着对您的模型进行全局控制,并强化数据安全性。

  • 安全2:我知道这是很less见的,但有时PHP代码从服务器泄漏(即公众可见)。 如果包含您的查询,可能的攻击者知道您的模型。 这很奇怪,但我仍然想要发信号

  • 专案组:是的,创build高效的SQL SP需要一些特定的资源,有时更昂贵。 但是,如果你认为你不需要这些资源,只是因为你正在把你的查询集成到你的客户端中,那么你将会遇到严重的问题。 我会提到Web开发的类比:将视图与其他视图分开是很好的,因为您的devise人员可以使用自己的技术,而程序员可以专注于编写业务层。

  • 封装业务层:使用存储过程完全隔离其所属的业务:该死的数据库。

  • 快速testing:在您的shell下一个命令行,您的代码被testing。

  • 客户端技术的独立性:如果明天你想从PHP切换到别的东西,没问题。 好的,只要将这些SQL存储在一个单独的文件中也可以做到这一点,这是正确的。 另外,关于如果你决定切换sql引擎的评论中的好点,你会有很多工作要做。 无论如何,你必须有一个很好的理由,因为对于大项目和大公司来说,很less发生(主要是由于成本和人力资源pipe理)

  • 实施敏捷的3 +层开发:如果您的数据库与客户端代码不在同一台服务器上,则可能有不同的服务器,但只有一台用于数据库。 在这种情况下,当您需要更改SQL相关代码时,您不必升级任何php服务器。

好的,我认为这是我在这个问题上最重要的一点。 我开发了两种精神(SP与客户端),我真的很喜欢SP风格。 我只是希望Mysql为他们提供了一个真正的IDE,因为现在这是一个在屁股有限的痛苦

存储过程很好用,因为它们使您的查询组织得当,并允许您一次执行批处理。 存储过程通常是快速执行的,因为它们是预编译的,与每次运行时编译的查询不同。 这在数据库位于远程服务器的情况下具有重大的影响; 如果查询在PHP脚本中,则应用程序和数据库服务器之间会有多个通信 – 查询被发送,执行并返回结果。 但是,如果使用存储过程,则只需发送一个小的CALL语句而不是大而复杂的查询。

编程存储过程可能需要一段时间,因为它们有自己的语言和语法。 但是一旦你习惯了,你会发现你的代码真的很干净。

在性能方面,如果您使用存储过程,可能没有任何重大收益。

我会让我知道我的意见,尽pipe我可能不直接关系到这个问题:

正如在许多问题中,回答关于使用存储过程还是应用层驱动的解决scheme都依赖于将推动整体工作的问题:

  • 你想得到什么。

你正在尝试批量操作还是在线操作? 他们完全是交易吗? 这些操作如何经常发生? 数据库等待的工作量有多重?

  • 你有什么来获得它。

你有什么样的数据库技术? 什么样的基础设施? 你的团队是否在数据库技术方面受过充分的培 你的团队是否能够更好地构build一个数据库诊断解决scheme?

  • 得到它的时间。

没有关于这个的秘密。

  • build筑。

您的解决scheme是否需要分发到多个地点? 是您使用远程通信所需的解决scheme吗? 您的解决scheme是在多个数据库服务器上工作,还是可能使用基于集群的体系结构?

  • Mainteinance。

需要更改多less应用程序? 您是否有经过专门培训的维护解决scheme?

  • 更换pipe理层。

你看到你的数据库技术会在短期,中期,长期变化吗? 你是否会经常需要迁移解决scheme?

  • 成本

使用一个或另一个策略来实施该解决scheme需要多less成本?

这些点的总体将推动答案。 所以在决定使用或不使用任何策略时,你必须关心每一点。 存在使用存储过程优于应用层pipe理查询的情况,而使用基于应用层的解决scheme进行查询和使用最好的情况也是如此。

在以下情况下,使用存储过程往往更加适用:

  1. 您的数据库技术不能在短时间内更改。
  2. 您的数据库技术可以处理并行操作,表分区或其他策略,将工作负载分配到多个处理器,内存和资源(集群,网格)。
  3. 您的数据库技术与存储过程定义语言完全集成,即支持在数据库引擎内部。
  4. 你有一个开发团队不怕使用程序语言(第三代语言)来获得结果。
  5. 你想实现的操作是内置的或支持的数据库内(导出到XML数据,pipe理数据的完整性和适当与触发器,调度操作等)。
  6. 可移植性不是一个重要的问题,你不需要在短时间内将技术改变到你的组织中,即使这样做是不可取的。 一般而言,可移植性被应用程序驱动和分层开发人员视为一个里程碑。 从我的angular度来看,当您的应用程序不需要在多个平台上部署时,可移植性不是问题,当没有理由进行技术更改时,或者迁移所有组织数据的努力高于改变的好处。 通过使用应用程序层驱动的方法(可移植性),您可以从数据库中获得性能和价值,从而获得什么?(为什么要花费数千美元购买法拉利,开车时间不会超过60米/小时?)。
  7. 性能是一个问题。 首先:在多种情况下,通过使用单个存储过程调用,而不是来自另一个应用程序的多个数据请求,可以获得更好的结果。 而且,您需要执行的一些特性可能内置在您的数据库中,并且在工作量方面使用起来更便宜。 当你使用一个应用层驱动的解决scheme时,你必须考虑与数据库连接相关的成本,调用数据库,networkingstream量,数据包装(即使用Java或.NET),当隐含成本使用JDBC / ADO.NET调用,因为您必须将数据包装到代表数据库数据的对象中,因此,实例化在处理,内存和数据来自外部时会带来相关的成本。

在以下情况下,使用应用层驱动的解决scheme往往更加适用:

  1. 可移植性是一个重要的问题。
  2. 应用程序将部署到只有一个或less数数据库存储库的多个位置。
  3. 您的应用程序将使用沉重的面向业务的规则,这些规则需要与底层数据库技术无关。
  4. 你要考虑根据市场趋势和预算来改变技术提供者。
  5. 您的数据库没有与调用数据库的存储过程语言完全集成。
  6. 您的数据库function是有限的,您的要求超出了您使用数据库技术所能达到的要求。
  7. 您的应用程序可以支持外部调用所固有的损失,更多的是基于特定于业务的规则的事务处理,并且必须将数据库模型抽象为用户的业务模型。
  8. 并行化数据库操作并不重要,而且,数据库没有并行化function。
  9. 你有一个开发团队没有受过良好的数据库技术培训,使用基于应用程序驱动的技术可以提高生产力。

希望这可以帮助任何人问自己什么是更好的使用。

如果你的数据库是复杂的,而不是一个有回应的论坛types,但真正的仓储SP肯定会受益。 你可以把你所有的业务逻辑放在那里,而不是一个开发人员会关心它,他们只是叫你的SP。 我一直在做这个连接超过15个表是不好玩的,你不能向新的开发者解释这一点。

开发人员也无法访问数据库,太棒了! 把它留给数据库devise者和维护者。 如果你还决定表格结构将被改变,你可以隐藏在你的界面后面。 n-Tier,请记住?

高性能和关系型数据库并不是什么东西,就连MySQL InnoDB都不是很慢,现在MyISAM应该被抛出窗口。 如果你需要一个networking应用程序的性能,你需要正确的caching,memcache或其他。

在你的情况下,因为你提到'Web'我不会使用存储过程,如果它是数据仓库,我一定会考虑它(我们使用SP的仓库)。

提示:既然你提到了Web-project,那么关于nosql的解决方法呢? 另外,你需要一个快速的数据库,为什么不使用PostgreSQL呢? (试图在这里倡导…)

我曾经使用过MySql,而且我对SQL的理解最差,我花了相当多的时间使用Sql Server,我有一个数据层和一个应用层的清晰分离,我目前正在使用0.5TB的服务器。

有时候我没有使用ORM,所以感到沮丧,因为开发对于存储过程来说非常快,所以速度要慢很多。 我认为我们的许多工作可以通过使用ORM加快。

当您的应用程序达到临界质量时,ORM性能将受到影响,一个写得很好的存储过程将使您的结果更快。

作为一个性能的例子,我在应用程序中收集10种不同types的数据,然后将其转换为XML,我在存储过程中处理,我有一个调用数据库而不是10。

Sql真的擅长处理数据集,有一件让我感到沮丧的事情是,当我看到有人从原始表单中获取sql数据,并使用应用程序代码来遍历结果并格式化和分组时,这实际上是不好的做法。

我的build议是学习和理解SQL足够和你的应用程序将真正受益。

我build议你远离数据库特定的存储过程。

我经历了许多突然想要切换数据库平台的项目,并且SP内的代码通常不是非常便携的=额外的工作和可能的错误。

存储过程开发还要求开发人员直接访问SQL引擎,在这种情况下,项目中的任何人都可以通过代码访问来更改正常的连接。

关于你的模型/层/层的想法:是的,坚持。

  • 网站调用业务层(BL)
  • BL调用数据层(DL)
  • DL调用任何存储(SQL,XML,Web服务,套接字,文本文件等)

这样你可以维持层之间的逻辑层次。 IF和ONLY如果DL调用看起来非常慢,您可以开始摆弄Stored Procedures,但是如果您突然需要将数据库传输到一个全新的平台上,则可以将原始的非SP代码保存在某个地方。 所有的云托pipe业务,你永远不知道什么是下一个数据库平台…

我一直密切关注亚马逊AWS上的原因。

我会build议你不要使用存储过程:

  • 他们在MySQL中的语言是非常糟糕的
  • 没有办法将数组,列表或其他types的数据结构发送到存储过程
  • 一个存储过程不能改变它的接口; MySQL既不允许命名也不允许可选参数
  • 这使得部署应用程序的新版本变得更加复杂 – 比如说你有10个应用程序服务器和2个数据库,哪一个首先更新?
  • 你的开发人员都需要学习和理解存储过程语言 – 这是非常糟糕的(正如我之前提到的)

相反,我build议创build一个图层/库,并把所有的查询在那里

您可以

  • 更新这个库并将其发布到您的应用程序服务器上
  • 有丰富的数据types,如数组,结构等传递
  • unit testing这个库,而不是存储过程。

performance:

  • 使用存储过程会降低应用程序开发人员的性能,这是您关心的主要问题。
  • 在复杂的存储过程中识别性能问题是非常困难的(简单的查询要容易得多)
  • 您可以通过线路在单个块中提交查询批处理(如果启用了CLIENT_MULTI_STATEMENTS标志),这意味着如果没有存储过程,则不会再有任何延迟。
  • 应用程序端代码通常比数据库端代码缩放得更好

这里有很多信息让人迷惑,软件开发是一个进化的过程。 我们20年前做的事情现在不是最好的做法。 回到今天,使用经典的客户端服务器,您不会梦想除SP之外的任何东西。

这对于课程来说绝对是一匹马,如果你是一个大型组织,你将会使用多层次,可能是SP,但是你不会关心他们,因为一个专门的团队会把它们整理出来。

与之相反的是,我发现自己试图快速打开一个Web应用程序解决scheme,这充分满足了业务需求,离开开发人员(远离我)开发页面和SQL查询是非常快的,我定义了DB结构体。

然而,复杂性正在增长,没有一个简单的方法来提供API,我正在盯着使用SP来包含业务逻辑。 我认为这是行之有效的,我控制这一点,因为我可以build立逻辑,并提供一个简单的结果集,离岸开发商build立一个前端。

如果我发现自己的软件取得了巨大的成功,那么就会出现更多的问题分离,并且会出现不同的实施scheme,但现在SP是完美的。

你应该知道所有可用的工具集,并匹配它们是明智的开始。 除非你正在build立一个企业系统,否则快速和简单是最好的。