4

我希望能够为内容页面构建面包屑,但是一段内容所在的类别可以有无限的深度,所以如果不逐个获取每个类别,我不知道如何去做获取其父级等。这似乎是一种更简单的方法,但我无法弄清楚。

我有一个文章表

article_id
article_name
article_cat_id

我也有一个类别表

cat_id
cat_name
cat_parent

Cat parent 是另一个类别的 id,其中一个类别是子类别。

想象一篇深度为 5 个类别的文章,据我所知,我必须构建类似这样的面包屑(示例代码显然应该对输入进行转义等)

<?php
$breadcrumbs = array(
    'Category 5',
    'Content Item'
);
$cat_parent = 4;

while($cat_parent != 0) {
    $query = mysql_query('SELECT * FROM categories WHERE cat_id = '.$cat_parent);
    $result = mysql_fetch_array($query, MYSQL_ASSOC);
    array_unshift($breadcrumbs, $result['cat_name']);
    $cat_parent = $result['cat_parent'];
}
?>

这会给我

array(
'Category 1',
'Category 2',
'Category 3',
'Category 4',
'Category 5',
'Content Item'
)

我可以将其用于我的面包屑,但是我花了 5 个查询来完成它,这并不是最好的。

任何人都可以提出更好的解决方案吗?

4

2 回答 2

3

为了简单起见,这里有一些简单的选项:

  1. 坚持您的设计,使用递归/迭代方法并享受拥有简单代码的好处。真的,这会让你走得很远。作为奖励,从这里转移到性能更高的东西比从更复杂的设置转移更容易。

  2. 如果类别的数量不是很大,您可以选择所有类别并在 PHP 中构建层次结构。由于页面大小,获取 1 行与一大堆(比如几百行)所需的工作量几乎相同。这最大限度地减少了查询/网络旅行的次数,但增加了通过电缆传输的数据量。措施!

  3. 缓存层次结构并在每个 X 单位时间或添加/修改/删除类别时完全重新加载它。在最简单的形式中,缓存可以是一个 PHP 文件,它具有一个包含整个类别层次结构的嵌套变量结构,以及一个简单的节点索引。

  4. 使用嵌套集、路径枚举、闭包表等,创建一个附加表,在其中以某种方式展平层次结构。该表将使用类别表上的触发器进行维护。

我会选择(1),除非您相当确定在不久的将来您将拥有每秒几个用户的持续负载。(每秒 1 个用户每月进行 250 万次访问)。

简单的代码没有错。为不明显的加速而复杂的代码是错误的。

于 2011-04-05T21:44:59.360 回答
2

关系数据库中处理层次数据的常用方法有两种:邻接表模型嵌套集模型。您在此处的架构当前遵循邻接列表模型。查看此页面以获取一些示例查询。在 SO 上也可以看到这个问题,这里有很多很好的信息。

于 2011-04-05T21:10:33.980 回答