php - 具有 Laravel 关系的 MySQL 嵌套集模型

标签 php mysql performance nested-set-model

晚上好!

我正在开发一个应该允许 Laravel 具有基于 MySQL 嵌套集模型(lft 和 rgt 键)的关系的包。

图例:X、Y、Z、A、B、C为整数。

假设我们想将其用于 eshop 类别。

我的第一个任务是创建一个parent 关系。我设法创建了一个关系来找到当前类别的父级。我的查询看起来像:

select * from categories where lft < X and rgt > Y order by lft limit 1

这完全正确。但是,当我想加载比方说 100 个类别时,问题就出现了。那么,就是100个类别的一个sql查询:

select * from categories limit 100

和每个类别的父级的一个 sql 查询:

select * from categories where lft < X and rgt > Y order by lft desc limit 1

总共是 101 个 sql 查询。

这就是问题所在。我想使用一种称为 Eager Loading 的技术(将所有关系查询合并为一个查询)。但是该怎么做呢?

解决方案编号。 1

我的第一个解决方案是从以下位置收集所有 lft 和 rgt 键:

select * from categories limit 100

并创建如下所示的查询:

select * from categories where (lft < X or lft < Y or lft < Z ...)
and ( rgt > A or rgt > B or rgt > C ...) order by lft desc

但是,这个解决方案根本行不通。它返回类别的所有父项。

解决方案编号。 2

然后,我尝试用这个方法让它正常工作。原始查询看起来是一样的。

select * from categories limit 100

但是加载 parent 是完全不同的:

(select * from categories where lft < X and rgt > Y order by lft desc limit 1)
union all 
(select * from categories where lft < A and rgt > B order by lft desc limit 1)
union all...

此查询仅返回相关结果,这是完美的,但是要将父项添加到其子项,我必须(在 PHP 端)运行 foreach 循环遍历原始查询的所有结果(select * from categories limit 100) 在那个 foreach 里面我必须运行另一个遍历每个父级(从原始查询)和在第二个 foreach 里面,有一个比较逻辑,它使 10 000 (100 * 100) 循环加上比较 = looooooooooooong 执行.

解决方案编号。 3

于是我想到了另一种方案,这是我认为最好的方案。只是对第二种方案的改进。

原始查询:

select * from categories limit 100

关系查询:

(select categories.*, X as child_lft, Y as child_rgt from categories
where lft < X and rgt > Y order by lft desc limit 1)
union all
(select categories.*, A as child_lft, B as child_rgt from categories
where lft < A and rgt > B order by lft desc limit 1)
union all...

现在,在 PHP 端,我有一个包含原始查询结果的数组(100 项)和一个包含关系查询结果的数组(100 项)。改进之处在于,现在每个父结果都包含请求它的类别的 lft 和 rgt 键(child_lft 和 child_rgt)。现在,PHP 脚本要快得多。首先,我创建了一个包含所有父项的新数组(我们将其命名为 $parents),并且每个项目键($parents 中的值键)是标识请求它的类别的代码 (child_lft.child_rgt => 1.5)。这是一个迭代 100 次的 foreach。第二个 foreach 遍历原始查询的结果并检查 $parents 数组是否包含具有适合其 lft 和 rgt 键的键的值。所以又进行了 100 次迭代。总共 200 次迭代 = 完美!但是“关系查询”并没有我想要的那么快。

那么,还有其他方法吗?或者有没有办法在解决方案中进行我的 sql 查询。 3 更快?

感谢您的阅读。谢谢!

最佳答案

您可以只使用 Baum这几乎可以解决您在 Laravel 中尝试做的事情,并且涵盖了大部分极端情况。

关于php - 具有 Laravel 关系的 MySQL 嵌套集模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26129636/

相关文章:

php - 重新排序订单以提高仓库效率

php - 单元测试函数 php

php - 选择parent_id下的所有产品(表1)(表2 =类别)

sql - MySQL - Select语句,按每篇文章的评论数排序

循环遍历单元格时 C# Excel Interop 变慢

java - 效率 : generic array vs object array

php - laravel 4 不适用于 Windows XAMPP

php - jQuery 函数无法处理使用 Ajax 加载的数据

php - 这对 "spam"和 "automation bots"安全吗?

javascript - 如何在不损失性能的情况下不断移动 SVG 路径