繁体   English   中英

在 MySQL 和 PHP 中进行计算

[英]Doing calculations in MySQL vs PHP

语境:

  • 我们有一个 PHP/MySQL 应用程序。
  • 某些部分的计算直接在 SQL 中完成。 例如:过去 24 小时内创建的所有用户都将通过 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 Ponies @mu 太短了 @Tudor Constantin @tandu @Harley

我同意(并且很明显)高效的 WHERE 子句属于 SQL 级别。 但是,例如:

  1. 使用 NOW() - SQL 中的 1 天计算 24 个周期以选择过去 24 小时内创建的所有用户?
  2. 返回所有用户的大写名字和姓氏?
  3. 连接字符串?
  4. (想法,伙计们?)

属于 SQL 域的清晰示例:

  1. 特定的 WHERE 选择
  2. 嵌套的 SQL 语句
  3. 排序/排序
  4. 选择 DISTINCT 项目
  5. 计数行/项目

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

聚合、加入和过滤逻辑显然属于数据层。 它更快,不仅因为大多数数据库引擎都为此进行了 10 多年的优化,而且您可以最大限度地减少在数据库和 Web 服务器之间转移的数据。

另一方面,我使用过的大多数数据库平台在处理单个值方面的功能都很差。 诸如日期格式化和字符串操作之类的事情在 SQL 中很糟糕,您最好在 PHP 中完成这些工作。

基本上,将每个系统用于其构建目的。

在可维护性方面,只要发生的事情之间的划分清晰,将它们分离为逻辑类型应该不会造成太大问题,当然也不足以消除好处。 在我看来,代码的清晰度和可维护性更多的是关于一致性,而不是将所有逻辑放在一个地方。


回复:具体例子...

  1. 我知道这也不是你所指的,但日期几乎是一个特例。 您要确保系统生成的所有日期都是在 Web 服务器或数据库上创建的。 如果数据库服务器和网络服务器被配置为不同的时区(我已经看到这种情况发生),否则会导致一些潜在的错误。 想象一下,例如,您有一个createdDate列,默认值为getDate() ,该列在 DB插入时应用。 如果您要插入一条记录,那么使用PHP 中生成的日期(例如date("Ymd", time() - 3600) ,选择过去一小时内创建的记录,您可能不会得到您期望的结果。至于是哪一层)你应该这样做,我更喜欢数据库,因为在示例中,它允许你使用列默认值。

  2. 对于大多数应用程序,我会在 PHP 中执行此操作。 将名字和姓氏结合起来听起来很简单,直到您意识到有时也需要称呼、头衔和中间名首字母。 另外,您几乎肯定会遇到这样的情况:您需要用户的名字、姓氏和组合称呼 + 名字 + 姓氏。 将它们连接到 DB 端意味着您最终会移动更多数据,尽管实际上,这非常小。

  3. 要看。 如上所述,如果您想单独使用它们,最好在性能方面将它们单独拉出并在需要时连接。 也就是说,除非您处理的数据集很大,否则可能还有其他因素(如您提到的,可维护性)具有更大的影响。

一些经验法则:

  • 生成增量 ID 应该发生在数据库中。
  • 就个人而言,我喜欢 DB 应用的默认设置。
  • 选择时,任何减少记录数量的事情都应该由 DB 来完成。
  • 做一些减少数据集 DB 端大小的事情通常是好的(就像上面的字符串示例一样)。
  • 正如你所说; 排序、聚合、子查询、连接等应该始终在 DB 端。
  • 此外,我们还没有谈论它们,但触发器通常是坏的/必要的。

您在这里面临一些核心权衡,平衡实际上取决于您的应用程序。

有些事情绝对应该 - 每次 - 总是在 SQL 中完成。 为许多任务排除一些异常(如日期) SQL 可能非常笨重,并且可能会让您在不合适的地方留下逻辑。 在您的代码库中搜索对特定列(例如)的引用时,容易错过包含在视图或存储过程中的那些。

性能始终是一个考虑因素,但根据您的应用程序和具体示例,性能可能不是很大。 您对可维护性的担忧可能非常有效,而且我提到的一些性能优势非常小,因此请注意过早优化。

此外,如果其他系统直接访问数据库(例如,用于报告或导入/导出),您将受益于数据库中的更多逻辑。 例如,如果您想直接从另一个数据源导入用户,则可以在 SQL 中实现诸如电子邮件验证功能之类的可重用功能。

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

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

  • 当我可以直接从 DB 获取结果集而无需进一步处理时,我会这样做 - 您的情况是一个带有简单WHERE子句的简单查询。 想象一下,当你有 1000 万用户并且你让他们使用 PHP,只需要 100 个用户时会发生什么 - 你猜对了 - 你的 Web 服务器很可能崩溃
  • 当您需要从一次2个或多个表中获取数据,同样,MySQL是比PHP更好
  • 当您需要计算记录时 - 数据库非常擅长
  • 我倾向于对 FK 约束进行应用程序级处理
  • 此外,我倾向于避免存储过程,更喜欢在应用程序级别实现该业务逻辑(当然,除非我们谈论的是巨大的数据集)。

总之,我想说你的同事在提出的案例中是对的

如果您将一半的逻辑放在数据库中,另一半放在 php 中,那么在 6 个月后进行更改时,您需要两倍的时间才能弄清楚发生了什么。

尽管如此,您的数据库查询应该有足够的逻辑,以便它们为您的 php 提供它需要的准确数据 如果您发现自己在 php 代码中遍历了数千条 mysql 记录,那么您就做错了。 但是,另一方面,如果您在 mysql 查询中运行 if / else 语句,那么您也做错了(可能只需要重写您的查询)。

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

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

可维护性往往会被熟悉程度所玷污。 如果您不熟悉 PHP,它就不会是您维护可维护性的最初选择——是吗?

在 SQL 中获取数据所花费的时间很耗时,但一旦完成,计算就会更加相同。 获取数据后,无论哪种方式都不会耗费太多时间,但在 SQL 中巧妙地执行此操作可以为大型数据集提供更好的结果。

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

一些基本点:

  1. MYSQL 中的日期格式很强,大多数格式在 Mysql 中都可用。 如果您有非常具体的日期格式,那么您可以使用 PHP。

  2. 字符串操作在 SQL 中很糟糕,最好在 PHP 中进行。 如果您没有需要做的大字符串操作,那么您可以在 Mysql SELECTs 中进行。

  3. 选择时,任何减少记录数的事情都应该由 SQL 而不是 PHP 来完成

  4. 排序数据应该总是在Mysql中完成

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

  6. 子查询和联接应始终位于 DB 端。 它将减少您的大量 PHP 代码。 当您需要同时从 2 个或多个表中获取数据时,SQL 比 PHP 好得多

  7. 想统计记录,SQL很棒。

对每一个的回答如下:

  1. 使用 NOW() - SQL 中的 1 天计算 24 个周期以选择过去 24 小时内创建的所有用户?

  2. 使用 PHP 创建日期和 WHERE 子句来查找数据。 在 PHP 中实现日期操作要快得多。

  3. 返回所有用户的大写名字和姓氏?

  4. 选择数据库中的所有用户,然后使用 PHP 将字符串大写。 同样,在 PHP 中实现要快得多。

  5. 连接字符串?

  6. 同样,用于字符串操作的 PHP。

(想法,伙计们?)

使用 PHP 进行所有数据操作,因为它更容易实现。 更清楚地说,在 PHP 中操作一个简单的$variable比在 SQL 中写出整个字符串操作更容易。 在 PHP 中操作,然后在 SQL 中更新数据库。

属于 SQL 域的清晰示例:

特定的 WHERE 选择 - 是的。

嵌套的 SQL 语句 - 我会重新评估你的 PHP 数据处理,但如果你必须,好的。

排序/排序 -排序肯定是 SQL 语句的工作,但您应该只在 SELECT 语句上排序。 任何其他排序,例如排序和更新数据库,都应该由 PHP 排序,因为再次操作 $vars 比写出 UPDATE SQL 语句更容易。

选择 DISTINCT 项目 - 是。

计数行/项目 - 使用: $Number_Of_Results = count($Results); 在 PHP 中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM