【问题标题】:How do I create nested categories in a Database?如何在数据库中创建嵌套类别?
【发布时间】:2011-08-06 01:06:14
【问题描述】:

我正在制作一个将嵌套类别的视频网站:

例如编程 -> C 语言 -> MIT 视频 -> 视频 1 编程 -> C 语言 -> 斯坦福视频 -> 视频 1 编程 -> Python -> 视频 1

这些类别和子类别将由用户动态创建。当人们以可导航菜单的形式创建它们时,我需要将它们展示出来,以便人们可以轻松地浏览集合。

有人可以帮助我如何创建这样一个数据库吗?

【问题讨论】:

标签: database nested categories


【解决方案1】:

制作一个包含以下字段的类别表:

  • CategoryID - 整数
  • CategoryName - String/Varchar/Whatever
  • ParentID - 整数

然后,您的 ParentID 将引用回其父级的 CategoryID。

例子:

CategoryID CategoryName ParentID
---------------------------------
1          Dog          NULL
2          Cat          NULL
3          Poodle       1
4          Dachsund     1
5          Persian      2
6          Toy Poodle   3

【讨论】:

  • 我如何构造一个查询来从这样的表中创建导航?有没有简单的方法?
  • Jake:我不知道您将如何进行自己的导航,但标准方法是首先使用“select * from”之类的查询来显示单个级别(例如顶级) tblCategories where ParentID 为 NULL”,所以你会得到 Dog 和 Cat。然后,当您单击 dog 时,您可以通过查询“Select * from tblCategories where ParentID = 1”来获得下一个级别,因为 1 是 Dog 的 categoryid。然后你以同样的方式继续往下钻。
【解决方案2】:

Quassnoi 说:

您应该使用嵌套集或父子模型。

我曾经实现它们。我能说的是:

如果您的类别表不经常更改,请使用嵌套集架构,因为在 select 子句上它速度很快,并且只需一个请求,您就可以获得给定条目的整个层次结构分支。但是在插入或更新子句中,更新 left 和 right(或下例中的 lower 和 upper)字段比父子模型需要更多时间。

还有一点,我必须承认,这很琐碎,但是:
直接在数据库中手动更改层次结构非常困难(可能在开发过程中发生)。所以,一定要先实现一个接口来玩嵌套集(更改父节点,移动分支节点,删除节点或整个分支等)

这里有两篇关于这个主题的文章:

最后一件事,我没有尝试过,但我在某处读到,嵌套集合表中可以有多个树,我的意思是多个根。

【讨论】:

    【解决方案3】:

    您应该使用nested setsparent-child 模型。

    Parent-child:

    typeid 父名 1 0 买家 2 0 卖家 3 0 裁判 4 1 电气 5 1 机械师
    SELECT  *
    FROM    mytable
    WHERE   group IN
            (
            SELECT  typeid
            FROM    group_types
            START WITH
                    typeid = 1
            CONNECT BY
                    parent = PRIOR typeid
            )
    

    将选择Oracle中的所有买家。

    Nested sets:

    typeid 小写名字 1 1 2 买家 2 3 3 卖家 3 4 4 裁判 4 1 1 电气 5 2 2 机械师
    SELECT  *
    FROM    group_types
    JOIN    mytable
    ON      group BETWEEN lower AND upper
    WHERE   typeid = 1
    

    将选择任何数据库中的所有买家。

    更多详情请参阅this answer

    Nested sets 更容易查询,但更难更新,更难构建树形结构。

    【讨论】:

      【解决方案4】:

      从您问题中的示例来看,您似乎希望给定类别可能有多个父级(例如,“MIT 视频 -> 视频 1 编程”以及“视频 -> 视频 1 编程” "),在这种情况下,仅添加 ParentID 列是不够的。

      我建议创建两个表:一个包含 CategoryID 和 CategoryName 列的简单类别表,以及一个包含 ParentCategoryID 和 ChildCategoryID 列的单独 CategoryRelationships 表。这样,您可以为任何特定类别指定任意数量的父子关系。甚至可以使用此模型建立双重关系,其中两个类别同时是彼此的父级和子级。 (在我脑海中,我想不出这个场景有什么用处,但至少它说明了模型的灵活性。)

      【讨论】:

      • 谢谢!这正是我想要的。例如,我希望在“逆向工程基础”和“编程语言”中都列出“汇编语言入门视频”。
      【解决方案5】:

      你需要的是基本的父子关系:

      Category (ID: int, ParentID: nullable int, Name: nvarchar(1000))
      

      【讨论】:

        【解决方案6】:

        存储表的 parent_id 的更好方法是将其嵌套在 ID 中 例如

        100000 编程 110000 C语言 111000 视频 1 编程 111100 C语言 111110斯坦福视频

        等等..所以你只需要一个脚本来处理 ID,这样第一个数字代表顶级类别,等等,随着你深入层次结构

        【讨论】:

        • 这是一种相当有趣的方式。您对如何查询此类数据有任何想法吗?
        • 这不是将您限制为 0-9 的 10 个顶级项目吗?使用零的原因是什么,您是否使用了一组整数来限制可能的孩子的数量?您将如何插入新项目并更新它们?
        猜你喜欢
        • 2022-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-21
        • 1970-01-01
        • 2016-05-04
        • 1970-01-01
        • 2019-01-04
        相关资源
        最近更新 更多