构建无限类别深度的面包屑 - PHP + SQL
我希望能够为内容页面构建面包屑,但是一段内容所在的类别可以具有无限的深度,所以我不知道如何在不逐一获取每个类别的情况下进行操作获取它的父级等。这似乎是一种更简单的方法,但我无法弄清楚。
我有一个文章表
article_id
article_name
article_cat_id
我也有一个类别表
cat_id
cat_name
cat_parent
Cat 父级是另一个类别的 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 个查询才能完成它,这并不是更好的选择。
谁能提出更好的解决方案?
I'd like to be able to build the breadcrumbs for a content page, however the categories a piece of content is in can have unlimited depth, so i'm not sure how to go about it without getting each category one by one and then getting its parent etc. It seems like it could be a simpler way but I can't figure it out.
I have an articles table
article_id
article_name
article_cat_id
I also have a categories table
cat_id
cat_name
cat_parent
Cat parent is the id of another category of which a category is a child.
Imagine an article which is 5 categories deep, as far as I can tell i'd have to build the breadcrumbs something like this (example code obviously inputs should be escaped etc)
<?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'];
}
?>
This would then give me
array(
'Category 1',
'Category 2',
'Category 3',
'Category 4',
'Category 5',
'Content Item'
)
Which I can use for my breadcrumbs, however its taken me 5 queries to do it, which isn't really preferable.
Can anyone suggest any better solutions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以下是一些按简单程度排列的简单选项:
坚持您的设计,使用递归/迭代方法并享受简单代码的好处。真的,这会让你走得很远。作为奖励,从这里转移到性能更高的东西比从更复杂的设置转移更容易。
如果类别数量不是很大,您可以选择所有类别并在 PHP 中构建层次结构。由于页面大小的原因,获取 1 行与获取一大堆(比如几百行)所需的工作量几乎相同。这最大限度地减少了查询/网络行程的次数,但增加了通过电缆传输的数据量。测量!
缓存层次结构,并在每个 X 时间单位或添加/修改/删除类别时完全重新加载它。在最简单的形式中,缓存可以是一个 PHP 文件,该文件具有包含整个类别层次结构的嵌套变量结构以及节点的简单索引。缓存
创建一个附加表,在其中以某种方式(使用嵌套集、路径枚举、闭包表等)展平层次结构。该表将使用类别表上的触发器进行维护。
我会选择(1),除非您相当确定在不久的将来每秒会有多个用户的持续负载。 (每秒 1 个用户每月的访问量为 250 万次)。
简单的代码没有什么问题。为了不明显的加速而使代码复杂化是错误的。
Here are some easy options in order of simplicity:
Stick with the design you have, use the recursive/iterative approach and enjoy the benefits of having simple code. Really, this will take you pretty far. As a bonus, it is easier to move from here to something more performant, than from a more complicated setup.
If the nr of categories isn't very large, you can select all of them and build the hierarchy in PHP. Due to pagesize the amount of work required to fetch 1 rows vs a whole bunch of them (say a few hundred) is pretty much the same. This minimizes the nr of queries/network trips, but increases the amount of data transported over the cable. Measure!
Cache the hierarchy and reload it entirely every X unit of time or whenever categories are added/modified/deleted. In it's simplest form, the cache could be a PHP file with a nested variable structure containing the entire category hierarchy, along with a simple index for the nodes.
Create an additional table in which you have flattened the hierarchy in some way, either using nested sets, path enumeration, closure table etc. The table will be maintained using triggers on the category table.
I would go for (1) unless you are fairly certain that you will have a sustained load of several users per second in the near future. (1 user per second makes 2,5 million visits a month).
There is nothing wrong with simple code. Complicating code for a speedup that isn't noticable is wrong.
在关系数据库中处理层次数据有两种常用的方法:邻接表模型和嵌套集模型。您此处的架构当前遵循邻接列表模型。请查看此页面了解一些示例查询。另请参阅此问题这里有很多很好的信息。
There are two commonly used methods of handling hierarchal data in relational databases: the adjacency list model and nested set model. Your schema here is currently following the adjacency list model. Check out this page for some example queries. See also this question here on SO with a lot of good information.