如何在mysql中保存一棵树?

发布于 2024-11-04 18:00:35 字数 180 浏览 0 评论 0原文

嘿!!

我想将一个类别保存到我的烹饪食谱中。

比如:肉酱面

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北笙凉宸 2024-11-11 18:00:35

如果您不介意围绕类别树的管理做一些家务,那么您可以使用一种方案,其中配方进入叶(最低)级别类别,并且所有其他类别关系都使用边界数字展平。您仍然具有管理树的递归关系,但您不会使用它来检索/查询食谱。

它看起来像这样:

Category
- Category ID
- Name
- (anything else you want to know about categories)
- Parent Category ID (FK to self / NULL for top level)
- Lower Bound
- Upper Bound

Recipe
- Recipe ID
- Category ID (FK - points to the lowest level / most specific category)
- (anything else you want to know about a recipe)

技巧是下界和上界。您可以像这样填充类别表:

Category: 
  Desserts ID=1 Parent=null {Lower=1, Upper=4}
  Cakes ID=2 Parent=1 {2, 4}
  Chocolate Cakes ID=3 Parent=2 {3, 3}
  Fruit Cakes ID=4 Parent=2 {4, 4}
  Appetizers ID=5 Parent=null {Lower=5, Upper=...}
...

例如,当您查询甜点食谱时,您会找到类别 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:

Category
- Category ID
- Name
- (anything else you want to know about categories)
- Parent Category ID (FK to self / NULL for top level)
- Lower Bound
- Upper Bound

Recipe
- Recipe ID
- Category ID (FK - points to the lowest level / most specific category)
- (anything else you want to know about a recipe)

The trick is the Lower Bound and Upper Bound. You populate the category table like this:

Category: 
  Desserts ID=1 Parent=null {Lower=1, Upper=4}
  Cakes ID=2 Parent=1 {2, 4}
  Chocolate Cakes ID=3 Parent=2 {3, 3}
  Fruit Cakes ID=4 Parent=2 {4, 4}
  Appetizers ID=5 Parent=null {Lower=5, Upper=...}
...

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.

海螺姑娘 2024-11-11 18:00:35

最简单的是“类别”表本身有一个外键,称为“父类别”或类似的东西。顶级类别(即膳食)在此字段中将为 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.

自控 2024-11-11 18:00:35

我认为最好的解决方案是不要将它们视为一棵树,而是走标签路线。所以你会有一个配方表和一个配方标签表。

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.

一口甜 2024-11-11 18:00:35

您可以将其作为一对多关系,例如:

    category
--------------
    id
    cat_name
    cat_parent

其中 cat_parent 引用父类别的 id

但是,请注意 MySQL 不支持递归查询,因此使用这样的设计,您无法进行深度子类别搜索。我读过可以使用不同的设计,我只是不记得来源了。

有关 MySQL 分层数据的更详细文章

You could do it as one-to-many relationship, example:

    category
--------------
    id
    cat_name
    cat_parent

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

深爱不及久伴 2024-11-11 18:00:35

因此,假设菜谱可能有一个名称、一个类别、一个成分列表——也许还有作者或其他元数据——并且您希望将所有菜谱放在树中。

最简单的方法是在菜谱表中添加另一列——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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文