php – 使用许多一对多关系(ORM)减少MySQL中的查询

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了php – 使用许多一对多关系(ORM)减少MySQL中的查询脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前正在使用基于Kohana框架构建的 PHPMysqL设计应用程序.我正在使用内置的ORM,事实证明它非常有用.一切正常,但我非常关心在某些页面上运行的查询数量.

设置
例如,有一个页面,您可以在其中查看充满各个部分的类别,这些部分又包含产品.这以表格格式列出.每个产品都有(可能)许多属性,标志,等级定价中断.这必须全部在表格中表示.

有多少疑问?
查询而言:类别必须查询其中的所有部分,并且这些部分必须查询它们包含的所有产品.还不错,但每个产品必须查询它的所有产品属性,层定价和标志.因此,向类别添加更多产品会使查询多次增加(因为我目前主要使用ORM).在一个部分中有几百个产品将导致几百个查询.小问题,但仍然不好.

至今…
所有键都被编入索引.我可以使用单个查询提取所有信息(请参阅下面的编辑),但是,正如您所能想象的那样,每个额外(例如)属性,这将导致每个产品在多行中分布大量冗余数据,国旗

我并不反对放弃ORM来显示应用程序的部分并继续使用查询构建甚至原始sql.

对此的解决方案实际上可能非常简单,我现在只是对它一无所知,老实说这是一种解脱.或许它不是.我不确定.如果我的任何解释都不足以理解问题,那就问一下,我会试着给出一个更好的例子. (编辑:给出更好的例子,见下文

虽然,旁注…
但有一点可能有一些相关性:虽然我总是希望最有效地设计应用程序,但这不是一个每天会被打几十次或几百次的网站.它更像是一个管理应用程序,可能不会被多个人同时使用.我无法预见太多的重新加载,因为页面上的大部分数据编辑都是通过AJAX完成的.那么,如果在这页面上运行了几百个查询(当前查看的部分中有多少产品不一致),每次加载此特定页面时,我是否应该关注多少?只是一个想法,即便如此,如果有可能解决上述主要问题,我宁愿这样做.

非常感谢你!

编辑
基于几个答案,似乎我没有充分解释自己.所以,让我发一个例子让你看看发生了什么.
在这个例子之前,我还应该做两个澄清:(1)还有一对多对多的关系,(2)你可能把我正在寻找的东西比作交叉表查询.

让我们简化并说我们有3个主要表:
产品(PRoduct_id,product_name,product_date_added)
product_attributes(product_attribute_id,product_id,value)
通知(notification_id,notification_label)

和1个支点:
product_notifications(notification_id,product_id)

我们将列出表格中的所有产品.在ORM中调用所有产品非常简单.
因此,根据每个“产品”,我们会列出product_name和product_date_added.但是,我们还需要列出所有产品属性.每种产品有0或更多.我们还必须显示产品的通知,其中还有0或更多.
所以目前,它的工作原理基本上是:

foreach ($products->find_all() as $product) //given that $products is an ORM object
{
   echo $product->product_id; //lets just pretend these are surrounded by htML
   echo $product->product_name;
   foreach ($products->product_attributes->find_all() as $attribute)
   {
       echo $attribute->value;
   }
   foreach ($products->notifications->find_all() as $notification)
   {
       echo $notification->notification_label; 
   }
 }

这当然过于简单,但这是我所说的原则.这已经很好了.但是,正如您所看到的,对于每个产品,它必须查询其所有属性获取适当的集合或行.
find_all()函数将返回以下行的查询结果:
SELECT product_attributes.* From product_attributes WHERE product_id =’#’,类似于通知.它为每个产品进行了这些查询.
因此,对于数据库中的每个产品,查询数量是该数量的几倍.
因此,尽管效果很好,但它不能很好地扩展,因为它可能会导致数百个查询.

如果我执行查询获取一个查询中的所有数据,则执行以下操作:

SELECT p.*,pa.*,n.*
From products p
LEFT JOIN product_attributes pa ON pa.product_id = p.product_id
LEFT JOIN product_notifications pn ON pn.product_id = p.product_id
LEFT JOIN notifications n ON n.notification_id = pn.notification_id

(再次过度简化).这将获取数据本身,但根据产品的每个属性通知,将返回带有冗余信息的额外行.

例如,如果我在数据库中有两个产品;一个有1个属性和1个标志,另一个有3个属性和2个标志,它将返回:

product_id,product_date_added,product_attribute_id,value,notification_id,notification_label
1,My Product,10/10/10,1,Color: red,Add This Product
2,Busy Product,10/11/10,2,Color: Blue,Update This Product
2,3,Style: New,Update This Product

不用说,这是一个很多冗余的信息.每个产品返回的行数将是它拥有的通知数量属性数.

ORM(或者,通常只是在循环中创建新查询)将每行中的所有信息合并到它自己的对象中,从而允许更逻辑地处理数据.那是摇滚乐.在一个查询调用信息消除了对可能数百个查询的需要,但是在行中创建了大量冗余数据,因此不会以简洁的集合返回(一个/多个)到多个关系数据.那是个难点.

对不起,这么久,试图彻底,哈哈,谢谢!

解决方法

一个有趣的替代方案是使用完全独立的模型处理您的读取和写入. (命令查询分离).复杂的对象模型(和ORMS)非常适合于复杂的业务行为建模,但是作为查询和向用户显示信息的接口很糟糕.你提到你并不反对放弃使用ORM渲染显示器 – 嗯,这正是许多软件架构师现在提出的建议.编写一个完全不同的界面(具有自己的优化查询),用于读取和报告数据. “读取”模型可以查询与ORM支持的“写入”模型一起使用的相同数据库,也可以是针对您需要生成的报告/屏幕进行非规范化和优化的单独数据库.

看看这两个演示文稿.这可能听起来有点矫枉过正(如果你的性能要求非常低,可能就是这样),但是这种技让这么多问题消失的感觉真是太棒了.

> Udi Dahan: “Command-Query
Responsibility Segregation”

> Greg Young: “Unshackle Your Domain”

脚本宝典总结

以上是脚本宝典为你收集整理的php – 使用许多一对多关系(ORM)减少MySQL中的查询全部内容,希望文章能够帮你解决php – 使用许多一对多关系(ORM)减少MySQL中的查询所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。