在MySQL vs PHP中进行计算

语境:

  • 我们有一个PHP / MySQL应用程序。
  • 计算的一些部分直接在SQL中完成。 例如:在过去24小时内创build的所有用户都将通过SQL查询(NOW() – 1天)返回,

有一位开发者和我之间正在进行辩论,我认为我们应该:

A.将所有计算/代码/逻辑保存在PHP中,并将MySQL视为一个“愚蠢”的信息存储库

他的观点:

B.根据什么更容易/更快来做混搭。 http://www.onextrapixel.com/2010/06/23/mysql-has-functions-part-5-php-vs-mysql-performance/

我正在考虑可维护性的观点。 他正在看速度(正如文章指出的那样,MySQL中的一些操作速度更快)。


@ bob-the-destroyer @tekretic @OMG小马@mu太矮了@Tudor Constantin @tandu @Harley

我同意(而且非常明显)高效的WHERE子句属于SQL级别。 然而,像这样的例子:

  1. 使用NOW()计算24个周期 – 在SQL中select1天,以select在过去24小时内创build的所有用户?
  2. 返回大写的所有用户的名字和姓氏?
  3. 连接一个string?
  4. (想法,乡亲?)

清除属于SQL域的示例:

  1. 具体的WHEREselect
  2. 嵌套的SQL语句
  3. 订购/分拣
  4. selectDISTINCT项目
  5. 计数行/项目

我会发挥每个系统的优势。

聚合,连接和过滤逻辑显然属于数据层。 速度更快,不仅因为大多数数据库引擎都有10多年的优化,而且还可以最大限度地减less在数据库和Web服务器之间移动的数据。

另一方面,我使用的大多数数据库平台都具有非常差的function来处理个别值。 事情喜欢date格式和string操作只是吸收在SQL中,你最好在PHP中做这个工作。

基本上,使用每个系统来完成它的function。

在可维护性方面,只要把发生的地方划分清楚,把这些划分成不同types的逻辑就不会造成太大的问题,当然也不足以带来好处。 在我看来,代码的清晰性和可维护性更多的是关于一致性,而不是把所有的逻辑放在一个地方。


Re:具体的例子

  1. 我知道这不是你所指的,但date几乎是一个特例。 您要确保系统生成的所有date都是在Web服务器或数据库上创build的。 否则会导致一些潜在的错误,如果数据库服务器和Web服务器曾经configuration为不同的时区(我见过这种情况发生)。 想象一下,例如,您有一个createdDate列,其中有一个由数据库插入的getDate()默认值。 如果你要插入一条logging,然后使用PHP中生成的date(例如date("Ymd", time() - 3600) ,select在最近一小时创build的logging,可能得不到你期望的logging。你应该这样做,我喜欢数据库,因为在例子中,它可以让你使用列的默认值。

  2. 对于大多数应用程序,我会在PHP中这样做。 结合名字和姓氏听起来很简单,直到你意识到你需要在那里的称呼,标题和中间首字母缩写。 另外,你几乎肯定会在你想要一个用户的名字,姓氏和结合称呼+名字+姓氏的情况下结束。 将它们连接在一起意味着你最终将移动更多的数据,虽然真的很小。

  3. 依靠。 如上所述,如果您想单独使用它们,则最好将性能方面的问题分别拔出并在需要时进行连接。 这就是说,除非你处理的数据集很大,否则可能还有其他因素(如你提到的可维护性)有更多的影响。

一些经验法则:

  • 生成增量ID应该发生在数据库中。
  • 就我个人而言,我喜欢我的默认值由数据库应用。
  • select时,任何减lesslogging数量的东西都应由数据库完成。
  • 它通常会减less数据集DB端的大小(就像上面的string示例一样)。
  • 正如你所说; sorting,聚合,子查询,连接等应始终在DB端。
  • 另外,我们没有提到它们,但触发器通常是不好的/必要的。

这里有几个核心的权衡取舍,而平衡真的取决于你的申请。

有些东西绝对应该每次都要用SQL来完成。 排除一些例外情况(比如date事件),对于很多任务来说,SQL可能非常笨重,并且可能会让逻辑处于不正确的位置。 当你search你的代码库时,你可能容易忽略包含在视图或存储过程中的内容。

性能总是一个考虑因素,但根据你的应用程序和具体的例子,可能不是一个大的。 您对可维护性的担忧,可能非常有效,以及我提到的一些性能优势都非常轻微,所以要小心不成熟的优化。

另外,如果其他系统直接访问数据库(例如报告或导入/导出),则可以从数据库中获取更多的逻辑。 例如,如果要直接从其他数据源导入用户,则可以在SQL中实现类似电子邮件validationfunction的可重用function。

简短的回答:这取决于。 🙂

我不喜欢重新发明轮子。 我也喜欢使用最好的工具来完成需要完成的任务,所以:

  • 当我可以从数据库直接得到结果集没有进一步处理,我这样做 – 你的情况是一个简单的查询与一个简单的WHERE子句。 想象一下,当你有一千万用户时,你会得到他们到PHP,只需要100人 – 你猜对了 – 你的Web服务器很可能会崩溃
  • 当你需要一次从2个或多个表中获取数据时,MySQL又比PHP好得多
  • 当你需要计数logging – 数据库是伟大的
  • 我倾向于赞成应用程序级别处理FK约束
  • 另外,我倾向于避免存储过程,宁愿在应用程序级别实现业务逻辑(当然,除非我们正在讨论大量的数据集)。

总之,我想说你的同事在提交的案例中是正确的

如果你把一半的逻辑放在数据库中,另一半放在php中,那么当你进行改变的时候,在6个月的时间里,你需要花两倍的时间来弄清楚发生了什么。

话虽如此, 你的数据库查询应该有足够的逻辑,以便他们提供你所需要的数据 。 如果你发现自己在你的php代码中循环了数千个mysqllogging,那么你做错了什么。 在规模的另一端,如果你在你的mysql查询中运行if / else语句,你也在做一些错误的事情(可能只是重写你的查询)。

我会避开存储过程。 虽然它们在理论上是一个很好的概念,但通常可以在PHP中以相同的结果完成更快的开发时间,而且还可以获得知道所有逻辑的位置的额外好处。

随着结果集的增加,MySQL将会扩展得更好。 坦率地说,将数据库视为“哑数据”存储库是浪费资源…

可维护性往往被熟悉感所污染。 如果你不熟悉PHP,那么这不是你可维护性的最初select – 是吗?

在SQL中获取数据所花费的时间是非常耗时的,但是一旦完成的计算完全相同。 在获取数据之后,两种方法都不会浪费时间,但是在SQL中巧妙地执行它可以为大型数据集提供更好的结果。

如果您从MYSQL中获取数据,然后在PHP中对获取的数据进行计算,那么最好是获取所需的结果并避免PHP处理,因为这会增加更多的时间。

一些基本点:

  1. MYSQL中的date格式是强大的,大多数格式都可以在Mysql中使用。 如果你有非常具体的date格式,那么你可以做PHP。

  2. string操作只是吸收SQL,更好的做PHP的工作。 如果你没有大的string操作需要做,那么你可以在MySQL SELECTs中做到这一点。

  3. select时,任何减lesslogging数量的东西都应该由SQL来完成,而不是由PHP来完成

  4. 订购数据应该始终在Mysql中完成

  5. 聚合应该始终在Mysql中完成,因为数据库引擎是专门为此devise的。

  6. 子查询和联接应该始终是DB端。 它会减less你的PHP代码。 当你需要从两个或多个表中一次获取数据时,SQL再次比PHP好

  7. 要计数logging,SQL是伟大的。