【问题标题】:How do I represent a Tree Structure in a mySQL table如何在 mySQL 表中表示树结构
【发布时间】:2013-05-23 02:10:52
【问题描述】:

这棵树有以下特点:

  1. 每个节点可以有多个父节点和多个子节点。
  2. 节点的父节点可以有不同的深度。

示例

我正在尝试表示如下的类别结构:

桌面和移动应用程序

桌面和移动应用程序->Android 应用程序

桌面和移动应用程序->Android 应用程序->游戏

桌面和移动应用程序->Android 应用程序->游戏->动作

桌面和移动应用程序->游戏

桌面和移动应用程序->游戏->动作

桌面和移动应用程序->游戏->冒险

桌面应用程序

桌面应用程序->游戏

桌面应用程序->游戏->动作

桌面应用程序->游戏->冒险

iPhone 应用程序

桌面应用程序->游戏

桌面应用程序->游戏->动作

桌面应用程序->游戏->冒险

尝试使用嵌套集算法,我最终得到了多个具有不同类别 ID 和不同深度的“游戏”类别。

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    简单的方法是构造一个表格,如下所示:

    类别
    类别ID
    家长ID
    姓名

    您的数据如下所示:

    1, 0, '桌面和移动应用'
    2, 1, 'Android 应用'
    3、2、“游戏”
    4, 3, '动作'
    5, 1, '游戏'
    6, 5, '动作'
    7, 5, '冒险'

    8, 0, '桌面应用'
    9、8、“游戏”

    你会像这样查询它: select * from Categories where ParentId = 1 将返回 Android 应用程序和游戏。要获得游戏的子类别,您可以执行select * from Categories where ParentId = 5,这将返回动作和冒险。


    更新 为了将单个项目与多个类别相关联,您需要一个额外的表:

    xref_CategoriesItems
    类别ID
    物品编号

    这将允许任何单个项目与多个类别相关联。假设您有一个桌面应用程序需要同时出现在桌面应用程序 > 游戏和桌面和移动应用程序 > 游戏中。

    您的表格将包含第 1 项的以下数据:
    3、1
    9、1

    当查看特定类别中的项目时,您将执行以下操作:

    select I.*
      from items I
        inner join xref_CategoriesItems XCI on (XCI.ItemId = I.ItemID)
      WHERE (XCI.Category = @CategoryId)
    

    查看特定项目属于哪些类别:

    select C.*
      from categories C
        inner join xref_CategoriesItems XCI on (XCI.CategoryId = C.CategoryId)
      where (XCI.ItemId = @ItemId)
    

    如果您需要所有子记录,则查询特定类别下的所有项目会稍微复杂一些。基本上,您需要将 xref_categories 与类别进行递归连接以获取子项。我不记得如何在 MySQL 的 sql 版本中表达它;但是以下内容可能会很好了解:Using MySQL query to traverse rows to make a recursive tree

    【讨论】:

    • 我已经做到了这一点,但是,同一个类别“游戏”现在有两个 CatID - 3 和 5。这给我带来了两个困难。 1)我现在必须将 Cat3 中的每个产品也与 Cat5 相关联。这会产生重复性和数据开销。 2)创建新类别是一个困难的过程,因为我们无法真正利用现有的类别。我们需要从头开始创建所有类别,然后将产品与它们关联起来。 --- 如果有办法用单个 ID 存储“游戏”,那么我会避免上述复杂性。
    • @AmarMond:我明白了。你又少了一块。我会更新我的答案。
    【解决方案2】:

    您要的不是真正的树,而是图表。特别是它是一个有向无环图(DAG)。 Here 这是一个关于将 DAG 存储在关系数据库中的链接。

    使用传统的类别树结构可能更容易,并在项目/类别链接表的帮助下允许项目位于多个类别中。

    【讨论】:

      【解决方案3】:

      另一种方法是在您存储的任何项目上使用标签而不是类别。从您给出的示例中,这甚至可能更合适-您将使用“桌面”和“移动”标签,而不是“桌面和移动应用程序”、“桌面应用程序”和“移动应用程序”。具有这两者的项目自然会属于第一类。

      参考:How to store tags in MySQL tags, one field in total or one filed for each tag?

      【讨论】:

        猜你喜欢
        • 2023-03-14
        • 1970-01-01
        • 2018-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多