在MySQL过程中处理树

cyp*_*her 4 mysql recursion stored-procedures hierarchical-data

这个想法很简单 - 我有两个表,类别和产品.

分类:

id | parent_id | name               | count
1    NULL        Literature           6020
2    1           Interesting books    1000
3    1           Horrible books       5000
4    1           Books to burn        20
5    NULL        Motorized vehicles   1000
6    5           Cars                 999
7    5           Motorbikes           1
...
Run Code Online (Sandbox Code Playgroud)

产品介绍:

id | category_id | name
1    1             Cooking for dummies
2    3             Twilight saga
3    5             My grandpa's car
...
Run Code Online (Sandbox Code Playgroud)

现在显示时,父类别包含所有子类别的所有产品.任何类别都可能有子类别.表结构中的count字段包含(或至少我希望它包含)此特定类别中显示的所有产品的计数.在前端,我使用简单的递归函数选择所有子类别,但是我不太确定如何在SQL过程中执行此操作(是的,它必须是SQL 过程).这些表包含有关hundread类别的任何种类,有超过10万种产品.
有任何想法吗?

Wri*_*ken 5

Bill Karwin对层次数据做了一些不错的幻灯片,而当前的Adjacency Model肯定是专业人士,但它并不适合这个(获得一个完整的子树).

对于我的Adjacency表,我通过存储/缓存路径(可能在脚本中,或在'更新前触发'中)来解决它,在更改parent_id id时,会创建一个新的路径字符串.您当前的表格如下所示:

id | parent_id | path    | name               | count
1    NULL        1         Literature           6020
2    1           1:2       Interesting books    1000
3    1           1:3       Horrible books       5000
4    1           1:4       Books to burn        20
5    NULL        5         Motorized vehicles   1000
6    5           5:6       Cars                 999
7    5           5:7       Motorbikes           1
Run Code Online (Sandbox Code Playgroud)

(选择你喜欢的id中找不到的任何分隔符)

所以,现在要从类别+子类别中获取所有产品:

SELECT p.*
FROM categories c_main
JOIN categories c_subs
ON c_subs.id = c_main.id 
   OR c_subs.path LIKE CONCAT(c_main,':%')
JOIN products p
ON p.category_id = c_subs.id
WHERE c_main.id = <id>
Run Code Online (Sandbox Code Playgroud)