【问题标题】:SQL statements vs MVC data access layer in PHPPHP 中的 SQL 语句与 MVC 数据访问层
【发布时间】:2013-02-11 13:30:52
【问题描述】:

现代 MVC 框架有自己的数据访问层实现,不需要编写 SQL 语句。在性能和可扩展性方面,是否有任何缺点,例如在使用时

$user = User::where('email', '=', $email)->first(); 

而不是在原始 SQL 中使用准备好的语句,例如

$user = DB::connection()->pdo->prepare("SELECT * from users where `email` = ? "  ) ;

由于 Laravel 和 Cakephp 等 MVC 框架也允许使用后一种方法,我不确定这两种方法在性能和可扩展性方面哪个更好。

【问题讨论】:

  • Laravel 重新标记问题。熟悉它的人会看到您的帖子,您可能会得到快速回复。
  • 原始查询 ~ 查询生成器 >>>> 活动记录。原始查询和查询构建器仅相差几分之一秒,可以忽略不计。但是对于复杂的查询,活动记录非常慢(公平地说,复杂的查询不是活动记录的主要目的。使用正确的工具)。

标签: php domain-driven-design data-access-layer laravel


【解决方案1】:

咆哮:
你所说的“现代 MVC 框架”(除了少数例外)与实现 MVC 相去甚远。而那些“不需要SQL语句的层”实际上在大型项目(应该实际使用MVC的地方)中是极其有害的。

我的建议是避免使用任何内置的 ORM 或查询构建器。与所谓的“mvc 框架”捆绑在一起的 ORM 通常是 active record 的实现,它的用例极其有限。基本上,如果您仅使用基本的 CRUD 操作(没有 JOINs 或其他高于初学者级别的 sql 查询),则基于 AR 的域实体实现是实用的和只有简单的属性验证(没有交叉检查的字段或与其他实体的交互)。从技术上讲,您可以在更复杂的情况下使用活动记录实例,但随后您将开始招致 technical debt

最好的选择是将域逻辑与存储逻辑分开,并分别为模型层的每个方面实现domain objectsdata mappers

【讨论】:

  • 谢谢。我以前没有使用过数据映射器/orm 库。基本上,我正在寻找在抽象层中使用我定制的 SQL 语句的正确方法,因为我觉得需要自己编写 SQL 查询,尤其是复杂查询。这是使用 ORM 库/数据映射器的正确方法吗?或者在使用数据映射器时这是可以接受的做法吗?有什么建议吗?
  • “数据映射器”不是库。它是一种设计模式。如果您需要处理复杂的查询,那么这是推荐的方法。
  • 我明白了。当您说“‘不需要 SQL 语句的层’实际上在大型项目(应该实际使用 MVC)中极其有害”时,您是指普通 MVC 框架的抽象层“有害”吗?跨度>
  • @Edville ,我指的是 “实现不需要编写 SQL 语句的数据访问层” 部分。
【解决方案2】:

是的,在性能和可扩展性方面都存在缺陷。

所有这些 ORM 和 AR 仅适用于基本查询。
但是当涉及到一些复杂的问题时,它们要么变得难以忍受,要么变得束手无策。
没有办法在这些时髦的运算符中注入“USE INDEX”、“DELAYED”或类似的性能提升命令。

可扩展性也是如此。
每次你要使用任何非标准的运算符时,你都会摸不着头脑。

还有一个便携性问题。
SQL 是网络开发人员的通用语,每个人都可以阅读和编写它。 而专有的 ORM 可以修复它们。

尽管如此,您的第二个代码同样丑陋且无法使用。

$user = DB::connection()->pdo->prepare("SELECT * from users where email=?");

DB::connection()->pdo->prepare() 不返回任何用户。它返回一个语句句柄,必须在以下几行中使用该句柄才能获取实际的用户信息。
在脚本中添加大量无用代码。
这是从标量中选择的序数情况。尝试使用INSERT 或仅使用IN() 语句,您的代码将被炸到几个屏幕高。

为什么不让它真正获得用户信息?

$user = DB::conn()->getRow("SELECT * from users where email=?s",$email);

看 - 你保留了你的 SQL 并使它可用。

【讨论】:

    【解决方案3】:

    当然,您总会有运行类和组装查询的开销。

    但它可以帮助您防止错误。诸如“是id =”之类的错字不会发生(或不应该)。除了那些层已经为你做了很多事情。

    像转义、解析、验证等...所以要承担开销,但要确保不会发生很多故障或安全问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-21
      • 2013-06-21
      • 2012-12-05
      • 1970-01-01
      • 2017-10-19
      • 1970-01-01
      • 2016-07-22
      • 2010-10-16
      相关资源
      最近更新 更多