如何在数据库中创建嵌套类别?

时间:2009-05-29 14:11:20

标签: database nested categories

我正在创建一个视频网站,其中的类别将被嵌套:

e.g。编程 - > C语言 - > MIT视频 - >视频1      编程 - > C语言 - >斯坦福视频 - >视频1      编程 - > Python - >视频1

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

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

6 个答案:

答案 0 :(得分:12)

使用以下字段创建类别表:

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

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

示例:

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

答案 1 :(得分:8)

Quassnoi说:

  

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

我曾经实施过这两种方法。我能说的是:

如果您的类别表不经常更改,请使用嵌套集架构,因为在select子句中它很快且只有一个请求,您可以获得给定条目的层次结构的整个分支。但是在插入或更新子句上,比父子模型花费更多时间来更新左侧和右侧(或下面示例中的下部和上部)字段。

另一点,我必须承认相当微不足道,但是:
直接在数据库中手动更改层次结构非常困难(可能在开发期间发生)。因此,请务必首先实现一个接口以使用嵌套集(更改父节点,移动分支节点,删除节点或整个分支等)。

以下是有关该主题的两篇文章:

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

答案 2 :(得分:5)

从您问题中的示例看,您似乎希望某个类别可以拥有多个父母(例如,“MIT视频 - >视频1编程”以及“视频 - >视频1编程“),在这种情况下,简单地添加一个ParentID列是不够的。

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

答案 3 :(得分:4)

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

Parent-child

typeid parent name

1      0      Buyers
2      0      Sellers
3      0      Referee
4      1      Electrical
5      1      Mechanic
SELECT  *
FROM    mytable
WHERE   group IN
        (
        SELECT  typeid
        FROM    group_types
        START WITH
                typeid = 1
        CONNECT BY
                parent = PRIOR typeid
        )

将选择Oracle中的所有买家。

Nested sets

typeid lower  upper  Name
1      1      2      Buyers
2      3      3      Sellers
3      4      4      Referee
4      1      1      Electrical
5      2      2      Mechanic
SELECT  *
FROM    group_types
JOIN    mytable
ON      group BETWEEN lower AND upper
WHERE   typeid = 1

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

有关详细信息,请参阅this answer

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

答案 4 :(得分:0)

您需要的是基本的亲子关系:

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

答案 5 :(得分:0)

存储表的parent_id的更好方法是将其嵌套在ID中 e.g

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

等等。所有你需要一个脚本来处理ID,这样第一个数字代表顶级类别,等等,当你进入更深层次的层次结构