如何在mysql中保存一棵树?
嘿!!
我想将一个类别保存到我的烹饪食谱中。
比如:肉酱面
meal-->noodle_dishes-->italian-->spaghetti_bolognese
如何保存这样的遗产?
谢谢
Hy!!
I want to save a category to my cooking recipes.
Like: Spaghetti Bolognese
meal-->noodle_dishes-->italian-->spaghetti_bolognese
How to save such a inheritance?
THX
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您不介意围绕类别树的管理做一些家务,那么您可以使用一种方案,其中配方进入叶(最低)级别类别,并且所有其他类别关系都使用边界数字展平。您仍然具有管理树的递归关系,但您不会使用它来检索/查询食谱。
它看起来像这样:
技巧是下界和上界。您可以像这样填充类别表:
例如,当您查询甜点食谱时,您会找到类别 ID 介于蛋糕类别下限和上限之间(即 2 到 4 之间)的所有食谱。
为了实现此目的,您需要具有程序代码,每当您对类别层次结构进行更改时,该代码都会返回并重新计算类别表中的所有下限和上限。因为与食谱的改变相比,这种情况应该很少发生。如果你想优雅一点,你可以想办法将重新计算限制在受影响的区域。
警告说明,为了简单地解释这个概念,我根据类别 ID 设置了下限和上限。显然,您不能使用增量 ID 来实现此目的,因为您的类别必须进行排序。因此,您的类别表需要第二个候选键,当您在层次结构更改时进行递归限制计算时,可以重新计算该候选键。因此,在查询时,您将使用真实(递增)类别 ID 来查找叶类别,然后使用该类别记录的下限和上限来过滤其他类别,并连接到符合您条件的食谱。
If you don't mind doing some housework around the management of your category tree, then you can use a scheme whereby the recipe goes into the leaf (lowest) level cateogry and all of the other category relationships are flattened out using bounding numbers. You would still have the recursive relationship for managing the tree but you wouldn't use it to retrieve/query for recipies.
Here is what it would look like:
The trick is the Lower Bound and Upper Bound. You populate the category table like this:
So when you query for recipies that are deserts, for example, you find all recipies that have a Category ID between the lower bound and upper bound of the Cakes category (i.e. between 2 and 4).
In order to make this work, you need to have procedural code that will go back and recalculate all of your lower and upper bounds in your categories table whenever you make a change to the categories hierarchy. Since this is something that should happen rarely by comparison to changes to recipies. If you want to be elegant, you can find ways to limit the recalculation to just the impacted areas.
A warning note, for simplicity of explaining the concept I've set the lower and upper limits based on the category ID. Obviously you can't use an incremental ID for this purpose since your categories have to be sorted. Therefore your categories table needs a second candidate key which can be recalculated when you do your recursive limit calculation at hierarchy change time. So at query time you are using the real (incrementing) category ID to find the leaf category and then using the lower and upper bounds from that category record to filter other categories and do a join out to recipies that fit your criteria.
最简单的是“类别”表本身有一个外键,称为“父类别”或类似的东西。顶级类别(即膳食)在此字段中将为 NULL。
Simplest would be for the "Category" table to have a foreign key on itself, called "parent category" or something similar. Top level categories (i.e. meal) would have NULL in this field.
我认为最好的解决方案是不要将它们视为一棵树,而是走标签路线。所以你会有一个配方表和一个配方标签表。
I think the best solution is to not treat them as a tree, and instead go the tag route. So you would have a recipe table and a recipe tag table.
您可以将其作为一对多关系,例如:
其中 cat_parent 引用父类别的 id
但是,请注意 MySQL 不支持递归查询,因此使用这样的设计,您无法进行深度子类别搜索。我读过可以使用不同的设计,我只是不记得来源了。
有关 MySQL 分层数据的更详细文章
You could do it as one-to-many relationship, example:
where cat_parent references to id of parent category
However, be aware that MySQL does not support recursive queries, so using such design, you cannot for example do deep subcategory search. I've read it is possible using different design, I just cannot remember the source.
More detailed article on MySQL hierarhical data
因此,假设菜谱可能有一个名称、一个类别、一个成分列表——也许还有作者或其他元数据——并且您希望将所有菜谱放在树中。
最简单的方法是在菜谱表中添加另一列——parent_recipe_id——然后假设那些具有父ID的行是“根”并且应该作为基本类别呈现。
(克里斯建议单独的“类别”或配方组表对于树结构会更加明确。)
So assuming recipe might have a name, a category, a list of ingredients-- and perhaps an author or other metadata -- and you want to place all your recipes in a tree.
The dead-simple way would be to add another column to the recipes table -- parent_recipe_id -- and then just assume that those rows with a parent ID are 'roots' and should be presented as basic categories.
(Kris' suggestion of a separate 'category' or recipe group table would be more explicit about the tree structure.)