假设我有 3 个表(仅重要列)
- 类别(catId
key
,parentCatId) - Category_Hierarchy (catId
key
, parentTrail, catLevel) - 产品(prodId
key
、catId、createdOn)
有一个单独的 Category_Hierarchy 表是有原因的,因为我在 Category 表上使用了填充它的触发器,因为 MySql 触发器像它们一样工作,如果我想使用auto_increment
值,我不能在触发器内的同一个表上填充列. 对于这个问题,这是无关紧要的。无论如何,这两个表是 1:1。
类别表可以是:
+-------+-------------+
| catId | parentCatId |
+-------+-------------+
| 1 | NULL |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 5 | 3 |
| 6 | 4 |
| ... | ... |
+-------+-------------+
类别_层次结构
+-------+-------------+----------+
| catId | parentTrail | catLevel |
+-------+-------------+----------+
| 1 | 1/ | 0 |
| 2 | 1/2/ | 1 |
| 3 | 1/2/3/ | 2 |
| 4 | 1/2/3/4/ | 3 |
| 5 | 1/2/3/5/ | 3 |
| 6 | 1/2/3/4/6/ | 4 |
| ... | ... | ... |
+-------+-------------+----------+
产品
+--------+-------+---------------------+
| prodId | catId | createdOn |
+--------+-------+---------------------+
| 1 | 4 | 2010-02-03 12:09:24 |
| 2 | 4 | 2010-02-03 12:09:29 |
| 3 | 3 | 2010-02-03 12:09:36 |
| 4 | 1 | 2010-02-03 12:09:39 |
| 5 | 3 | 2010-02-03 12:09:50 |
| ... | ... | ... |
+--------+-------+---------------------+
Category_Hierarchy 使获取类别从属树变得简单,如下所示:
select c.*
from Category c
join Category_Hierarchy h
on (h.catId = c.catId)
where h.parentTrail like '1/2/3/%'
它将返回类别 3 的完整从属树(即低于 2,即低于 1,即根类别),包括从属树根节点。排除根节点只是又一个where
条件。
问题
我想写一个存储过程:
create procedure GetLatestProductsFromSubCategories(in catId int)
begin
/* return 10 latest products from each */
/* catId subcategory subordinate tree */
end;
这意味着如果某个类别有 3 个直接子类别(下面有任意数量的节点),我将得到 30 个结果(每个从属树中 10 个)。如果它有 5 个子类别,我会得到 50 个结果。
最好/最快/最有效的方法是什么?如果可能的话,我想避免使用游标,除非它们与任何其他解决方案以及准备好的语句相比工作得更快,因为这将是对 DB 的最频繁调用之一。
编辑
由于一张图片可以讲述 1000 个单词,因此我将尝试使用图片更好地解释我想要什么。下图显示了类别树。这些节点中的每一个都可以有任意数量的与之相关的产品。图片中不包含产品。
所以如果我执行这个调用:
call GetLatestProductsFromSubCategories(1);
我想有效地获得 30 种产品:
- 来自整个橙色子树的 10 款最新产品
- 来自整个蓝色子树的 10 款最新产品和
- 来自整个绿色子树的 10 款最新产品
我不想从节点下的每个节点获得 10 个最新产品,catId=1
这意味着 320 个产品。