php – 从Laravel上的数据库中检索所有父/子记录(分层数据)

前端之家收集整理的这篇文章主要介绍了php – 从Laravel上的数据库中检索所有父/子记录(分层数据)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

对于类似遗留票证的系统,我有以下简化的数据库表结构.

messages
  id         INT
  parent_id  INT
  content    TEXT
  answer     TEXT
  ...

在列表中,我显示所有消息.单击消息时,我会显示其答案等.

问题是:现在我需要一个与此消息相关的所有父项和子项的列表结构,以及此消息在树中的位置.我怎样才能从数据库中检索它们?

我正在使用Laravel,但原始sql也可以帮助我找到方向.

例:

╔════╦═══════════╦════════════════════════╦═════════════════╗
║ id ║ parent_id ║        content         ║     answer      ║
╠════╬═══════════╬════════════════════════╬═════════════════╣
║  1 ║ NULL      ║ Hi,I have a problem   ║ I can't help    ║
║  2 ║ 1         ║ The problem persists   ║ Ok,what is it? ║
║  3 ║ 2         ║ Nevermind,I got this  ║ Oh,well.       ║
║  4 ║ 3         ║ Problem is back        ║ Which problem?  ║
║  5 ║ 4         ║ The same problem again ║ ...             ║
╚════╩═══════════╩════════════════════════╩═════════════════╝

显示id = 4的消息时,我应该能够显示如下列表:

消息历史:
– 嗨,我有问题
– 问题仍然存在
– 没关系,我明白了
– 问题又回来了
– 再次出现同样的问题

我只能想到一个循环和几个SQL查询执行,每个父和子,看起来像一个代码气味.

UPDATE

如Daan所述,这个问题似乎与How to create a MySQL hierarchical recursive query重复.

我决定不删除它,因为Ravan刚刚用Laravel方法回答了它,这有助于我解决问题,所以我将把它留在这里以备将来参考.

最佳答案
由于您正在进行分层操作,因此应使用策略从数据库中保存和检索此数据.

一种方法是使用Nested Set Model,这可以使它更容易.
Laravel有一个很好的解决方案,称为etrepat/baum,它也解释了它是如何工作的,我引用:

背后的理论,一个TL; DR版本

可视化嵌套集如何工作的简单方法是考虑围绕所有嵌套集的父实体
它的孩子,它的父母围绕着它等等.所以这棵树:

root
  |_ Child 1
    |_ Child 1.1
    |_ Child 1.2
  |_ Child 2
    |_ Child 2.1
    |_ Child 2.2

可以像这样可视化:

 ___________________________________________________________________
|  Root                                                             |
|    ____________________________    ____________________________   |
|   |  Child 1                  |   |  Child 2                  |   |
|   |   __________   _________  |   |   __________   _________  |   |
|   |  |  C 1.1  |  |  C 1.2 |  |   |  |  C 2.1  |  |  C 2.2 |  |   |
1   2  3_________4  5________6  7   8  9_________10 11_______12 13  14
|   |___________________________|   |___________________________|   |
|___________________________________________________________________|

数字代表左右边界.然后表可能
看起来像这样:

id | parent_id | lft  | rgt  | depth | data
 1 |           |    1 |   14 |     0 | root
 2 |         1 |    2 |    7 |     1 | Child 1
 3 |         2 |    3 |    4 |     2 | Child 1.1
 4 |         2 |    5 |    6 |     2 | Child 1.2
 5 |         1 |    8 |   13 |     1 | Child 2
 6 |         5 |    9 |   10 |     2 | Child 2.1
 7 |         5 |   11 |   12 |     2 | Child 2.2

要获得父节点的所有子节点,您

SELECT * WHERE lft IS BETWEEN parent.lft AND parent.rgt

为了得到孩子的数量,这是

(right - left - 1)/2

为了让一个节点及其所有祖先回到根节点,你

SELECT * WHERE node.lft IS BETWEEN lft AND rgt

正如您所看到的那样,查询将是递归的并且过于缓慢
普通的树突然很快.漂亮,不是吗?

猜你在找的MySQL相关文章