MySQL分层存储:搜索所有父/祖父/ /等。给定子节点id的节点?

时间:2011-04-21 20:21:46

标签: php mysql hierarchy hierarchical-data

我使用像这样的分层模型存储类别:

CATEGORIES
id | parent_id | name
---------------------
1  | 0         | Cars
2  | 0         | Planes
3  | 1         | Hatchbacks
4  | 1         | Convertibles
5  | 2         | Jets
6  | 3         | Peugeot
7  | 3         | BMW
8  | 6         | 206
9  | 6         | 306

然后,我将这些类别ID中的一个存储为实际数据,如下所示:

CARS
vehicle_id | category_id | name
-------------------------------
1          | 8           | Really fast silver Peugeot 206 
2          | 9           | Really fast silver Peugeot 306 
3          | 5           | Really fast Boeing 747
4          | 3           | Another Peugeot but only in Hatchbacks category

当搜索任何这些数据时,我想找到所有子/孙/孙子等节点。因此,如果有人想要查看所有“汽车”,他们会看到所有内容都是父母的“掀背车”,所以所有内容都是父节点“标致”,等等,任意级别。

因此,如果我列出一个“真正快速的标致206”,其category_id为1,3,6或8,我的查询应该能够“向上”树,找到更高级别的父母/祖父母该子类别。例如。搜索“8”类别中标致的用户应该找到列有类别6,3或1的任何标致 - 所有类别都是8的后代。

E.g。使用上述数据,在类别3中搜索“标致”实际上应该找到车辆1,2和4,因为车辆1和2具有类别祖先轨迹,其可以返回到类别3.参见?

很抱歉,如果我没有解释清楚。它很难!谢谢你。

注意:我已阅读the MySQL dev article on hierarchies

4 个答案:

答案 0 :(得分:1)

规范化模型很棒,但实际上不必查询它们。

只需将“路径”存储到类别表中的类别即可。像这样:path = / 1/3/4当你查询你的数据库时,例如“select .... where path like'/ 1/3 /%'”它会比多层次查询简单快捷...

答案 1 :(得分:0)

答案 2 :(得分:0)

我喜欢SitePoint提供的解释。它为您提供代码并解释其背后的理论。

http://blogs.sitepoint.com/hierarchical-data-database/

注意:此方法对于读取比写入更好。如果你经常写树,我会使用不同的算法。此方法针对读取(查找)进行了优化。

答案 3 :(得分:0)

您已将自己的数据表示为邻接列表模型,其querying in MySQL is best done using session variables。现在,这不是you can represent a hierarchy in a relational database的唯一方法。对于您的特定问题,我可能会使用materialized path方法,在这里您取消实际的类别表,而是在每个记录的基础上在您的汽车表上有一个类似Cars/Hatchbacks/Peugeot的列使用LIKE个查询。不幸的是,随着记录数量的增长,这将会很慢。现在,如果您知道层次结构的最大深度(例如,四个级别),则可以将其分解为单独的列,这样您就可以利用索引编制。