3

例如,“都乐香蕉”是一种产品,它列在“香蕉”类别下,当我打开“水果”类别时,我想看到“都乐香蕉”。

+ Food
|--+ Fruits
|------+ Bananas   
|------+ Apples
|--+ Vegetables
|------+ Onion
|------+ Spinach
4

8 回答 8

3

如果您正在寻找解决此问题的在线资源,“将树存储在数据库中”将是一个很好的搜索词组。

至于解决方案,请注意每个子类别可以有一个或零个父类别。因此,整个树可以存储在具有“父”字段的单个自引用表中。

使用您的示例树:

 ID  | PARENT | NAME
-----+--------+-------------
  1  |  null  | Food
  2  |   1    | Fruits
  3  |   2    | Bananas
  4  |   2    | Apples
  5  |   1    | Vegetables
  6  |   5    | Onion
  7  |   5    | Spinach
于 2009-09-13T16:44:49.880 回答
3

我通常使用非常适合数据库查询的左右树。每个节点都有一个 parentId、left 和 right 值。每个节点子节点都有一个左/右值,它位于父节点左右之间,这使得查找节点的所有子节点/父节点变得非常容易。它确实给插入带来了轻微的开销,但除非你插入很多,否则它不应该有太大的影响。

编辑:不过,只是一个警告,您需要在锁定的事务中进行插入/更新操作,否则树可能会搞砸。

于 2009-09-13T16:57:00.183 回答
1

具有 3 个字段的表“类别”。

  1. CategoryId 不为空(主键)
  2. ParentCategoryId 空
  3. 类别名称不为空

获取所有根类别

select * from Categories where ParentCategoryId is null

要获取某个特定类别的所有子类别:

select * from Categories where ParentCategoryId = 12
于 2009-09-13T16:45:14.527 回答
0

您可以使用带有 parent_category_id 的简单表结构并使用递归检索整个树或实现左/右值并使用预排序树遍历方法获取整个树。

于 2009-09-13T16:39:27.333 回答
0

如果您的意思是无限数量的级别,那么可以递归的自引用表。示例:StuffID、StuffName、StuffParentID(FK 到 Stuff ID)

对于有限数量的固定表:父子孙子

于 2009-09-13T16:41:15.613 回答
0
    CREATE TABLE [dbo].[Category](
    [CategoryId] [int] NOT NULL,
    [ParentCategoryId] [int] NULL,
    [CategoryName] [nvarchar](50) NOT NULL,
     CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 
    (
        [CategoryId] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON 

[PRIMARY]

GO

ALTER TABLE [dbo].[Category]  WITH CHECK ADD  CONSTRAINT [FK_Category_Category] FOREIGN KEY([ParentCategoryId])
REFERENCES [dbo].[Category] ([CategoryId])
GO

ALTER TABLE [dbo].[Category] CHECK CONSTRAINT [FK_Category_Category]
GO
于 2009-09-13T16:48:00.377 回答
0

对于无限层次结构,使用修改的前序树遍历算法

于 2009-09-13T17:04:53.650 回答
0

这是一种可能对您有用的不同方法。与 PARENT_ID 或 lft/rght 方法相比,它的维护成本略高,但检索更容易(并且更快)。

Dole 香蕉可以在产品表中。您有一个产品的 category_id。

我们需要允许一个产品有多个类别。这导致我们有一个 categories_products 连接表,其中产品可以有多个连接行。然后,我们必须决定是只在香蕉中添加 Dole 香蕉,还是在香蕉及其所有父母中添加。由于检索速度至关重要,我们将多乐香蕉放在其类别及其所有父类别中。多尔香蕉有三个类别产品连接。

使用这种结构,返回任何类别的所有项目既简单又快捷,只需一个查询。您不能在 PARENT_ID 方法中执行此操作(除非您对父母、祖父母等进行硬编码)。添加类别很容易。对产品进行分类需要在连接表中插入多行。删除和移动类别有点棘手。

于 2009-09-16T05:33:41.877 回答