【问题标题】:MySQL Nested Set Model with Laravel Relationships具有 Laravel 关系的 MySQL 嵌套集模型
【发布时间】:2018-10-21 17:50:09
【问题描述】:

晚上好!

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

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

假设我们想将其与 eshop 类别一起使用。

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

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

但加载父母却完全不同:

(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 循环(从类别限制中选择 * 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 倍?

感谢您阅读。谢谢!

【问题讨论】:

  • “晚安,先生们!”咳嗽。相当肯定有男性和女性程序员。
  • 我为侮辱女士道歉,我不是故意的。

标签: php mysql performance nested-set-model


【解决方案1】:

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

【讨论】:

猜你喜欢
  • 2023-02-20
  • 1970-01-01
  • 2016-12-14
  • 2014-01-08
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多