Cha*_*les 7 php mysql hierarchy hierarchical-data laravel
对于类似遗留票证的系统,我有以下简化的数据库表结构.
messages
id INT
parent_id INT
content TEXT
answer TEXT
...
Run Code Online (Sandbox Code Playgroud)
在列表中,我显示所有消息.单击消息时,我会显示其答案等.
问题是:现在我需要所有的表结构的父母和孩子的关系到这条消息,以及这个消息在树中的位置.我怎样才能从数据库中检索它们?
我正在使用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查询执行,每个父和子,看起来像一个代码气味.
如Daan所述,这个问题似乎与如何创建MySQL分层递归查询重复.
我决定不删除它,因为Ravan刚刚用Laravel方法回答了它,这有助于我解决问题,所以我将把它留在这里以备将来参考.
由于您正在执行分层操作,因此应使用一种策略来保存和从数据库中检索此数据。
一种方法是使用嵌套集模型,可以使其更容易。Laravel有一个很好的软件包,叫做etrepat / baum,它也解释了它是如何工作的,我引用:
可视化嵌套集工作方式的一种简单方法是,考虑围绕其所有子级的父实体,以及围绕其子级的父实体,等等。因此,这棵树:
root
|_ Child 1
|_ Child 1.1
|_ Child 1.2
|_ Child 2
|_ Child 2.1
|_ Child 2.2
Run Code Online (Sandbox Code Playgroud)
可以像这样可视化:
___________________________________________________________________
| 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
| |___________________________| |___________________________| |
|___________________________________________________________________|
Run Code Online (Sandbox Code Playgroud)
数字代表左边界和右边界。该表可能如下所示:
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
Run Code Online (Sandbox Code Playgroud)
要获取父节点的所有子节点,您可以
SELECT * WHERE lft IS BETWEEN parent.lft AND parent.rgt
Run Code Online (Sandbox Code Playgroud)
为了得到孩子的数量,
(right - left - 1)/2
Run Code Online (Sandbox Code Playgroud)
为了使节点及其所有祖先回到根,您可以
SELECT * WHERE node.lft IS BETWEEN lft AND rgt
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,在普通树上那些递归且速度过慢的查询突然变得非常快。漂亮,不是吗?
| 归档时间: |
|
| 查看次数: |
3550 次 |
| 最近记录: |