如何在mysql中保存树?

时间:2011-05-02 13:24:21

标签: mysql database-design

HY !!

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

喜欢: Spaghetti Bolognese

meal-->noodle_dishes-->italian-->spaghetti_bolognese 

如何保存这样的继承?

THX

5 个答案:

答案 0 :(得分:3)

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

以下是它的样子:

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介于Cakes类别的下限和上限之间(即介于2和4之间)。

为了使这项工作,你需要有程序代码,当你对类别层次结构进行更改时,这些程序代码将返回并重新计算类别表中的所有下限和上限。因为与收件人的更改相比,这种情况很少发生。如果您想要优雅,您可以找到将重新计算限制在受影响区域的方法。

警告说明,为了简化解释概念,我根据类别ID设置了下限和上限。显然,您不能为此目的使用增量ID,因为您的类别必须进行排序。因此,类别表需要第二个候选键,在层次结构更改时进行递归限制计算时可以重新计算。因此,在查询时,您使用实际(递增)类别ID来查找叶类别,然后使用该类别记录的下限和上限来过滤其他类别,并联接到符合您条件的收件人。

答案 1 :(得分:2)

最简单的是“类别”表在其自身上有一个外键,称为“父类别”或类似的东西。顶级类别(即用餐)在此字段中将为NULL。

答案 2 :(得分:1)

我认为最好的解决方案是不将它们视为树,而是转向标记路径。所以你会有一个食谱表和食谱标签表。

答案 3 :(得分:0)

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

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

其中cat_parent引用父类别的id

但是,请注意MySQL不支持递归查询,因此使用此类设计时,您无法进行深入的子类别搜索。我读过它有可能使用不同的设计,我只是记不起源。

More detailed article on MySQL hierarhical data

答案 4 :(得分:0)

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

简单的方法是在配方表中添加另一列 - parent_recipe_id - 然后假设那些父ID为“root”的行应该作为基本类别显示。

(Kris建议单独的'类别'或配方组表对树结构更明确。)