代表数据库中的产品分类

时间:2010-12-02 14:21:14

标签: database-design tree

我必须在数据库中表示具有父子关系的复杂产品分类。有人可以指导我这么做吗?

例如根可能是'所有产品' 然后可能在第二级我们有'电脑'和'家具' 像一棵树??

6 个答案:

答案 0 :(得分:2)

这是一个使用SQL Server 2005的简单树示例:

--go through a nested table supervisor - user table and display the chain
DECLARE @Contacts table (id varchar(6), first_name varchar(10), reports_to_id varchar(6))
INSERT @Contacts VALUES ('1','Jerome', NULL )  -- tree is as follows:
INSERT @Contacts VALUES ('2','Joe'   ,'1')     --                      1-Jerome
INSERT @Contacts VALUES ('3','Paul'  ,'2')     --                     /        \
INSERT @Contacts VALUES ('4','Jack'  ,'3')     --              2-Joe           9-Bill
INSERT @Contacts VALUES ('5','Daniel','3')     --            /       \              \
INSERT @Contacts VALUES ('6','David' ,'2')     --     3-Paul          6-David       10-Sam
INSERT @Contacts VALUES ('7','Ian'   ,'6')     --    /      \            /    \
INSERT @Contacts VALUES ('8','Helen' ,'6')     -- 4-Jack  5-Daniel   7-Ian    8-Helen
INSERT @Contacts VALUES ('9','Bill ' ,'1')     --
INSERT @Contacts VALUES ('10','Sam'  ,'9')     --

DECLARE @Root_id  char(4)

--get 2 and below
SET @Root_id=2
PRINT '@Root_id='+COALESCE(''''+@Root_id+'''','null')
;WITH StaffTree AS
(
    SELECT 
        c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
        FROM @Contacts                  c
            LEFT OUTER JOIN @Contacts  cc ON c.reports_to_id=cc.id
        WHERE c.id=@Root_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL)
    UNION ALL
        SELECT 
            s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
        FROM StaffTree            t
            INNER JOIN @Contacts  s ON t.id=s.reports_to_id
    WHERE s.reports_to_id=@Root_id OR @Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree

输出:

@Root_id='2   '
id     first_name reports_to_id Manager_id Manager_first_name LevelOf
------ ---------- ------------- ---------- ------------------ -----------
2      Joe        1             1          Jerome             1
3      Paul       2             2          Joe                2
6      David      2             2          Joe                2
7      Ian        6             6          David              3
8      Helen      6             6          David              3
4      Jack       3             3          Paul               3
5      Daniel     3             3          Paul               3

(7 row(s) affected)

更改@Root_id以获得不同的输出:

@Root_id=null
id     first_name reports_to_id Manager_id Manager_first_name LevelOf
------ ---------- ------------- ---------- ------------------ -----------
1      Jerome     NULL          NULL       NULL               1
2      Joe        1             1          Jerome             2
9      Bill       1             1          Jerome             2
10     Sam        9             9          Bill               3
3      Paul       2             2          Joe                3
6      David      2             2          Joe                3
7      Ian        6             6          David              4
8      Helen      6             6          David              4
4      Jack       3             3          Paul               4
5      Daniel     3             3          Paul               4

(10 row(s) affected)

答案 1 :(得分:1)

每条记录都有一个父ID。它指的是同一个表中的另一条记录。

根元素的父ID为NULL 当然,最好将其编入索引。

在一些用法中,对第一个直接兄弟姐妹也有一个记录点是有效的。

答案 2 :(得分:1)

我首先要确定你的树中是否有一个固定的,预定数量的级别,或者你是否需要动态添加级别。

在前一种情况下,一个结构可能是一组简单的表,例如'product _superclass','product_class& '产品'。 product_class可以使用product_class的外键,产品可以使用引用product_class的外键。

如果您不知道级别数,那么您可能只需要一个表(假设任何产品只有一个父级)。在这种情况下,每行可以选择引用同一个表中的父级。

固定数量的级别可以使查询更容易,更易读,而且灵活性显着降低。

答案 3 :(得分:1)

对于你所陈述的问题,没有一个“单一最好”的答案。

您可能希望避免将自己陷入单独的表(两个或更多)中的父/子关系,因为事情几乎立即变得混乱。

考虑使用更通用的“Product”表 - 并允许它引用Parent值(另一个Product记录的ID)。

最好将此模型化一点 -

但它可以分为“结构”,“产品(样式)”,然后是SKU(具有库存的可售物品)。 - SKU有时会根据产品类型进一步细分为UPC(EAN)(例如,Groceries为SKU提供多个UPC以进行季节性轮换)。

注意 - 然后可以针对相应的ID将属性归因于任何级别,并且突然您可以在继承行上访问这些属性。

答案 4 :(得分:1)

在SQL中管理树有许多不同的方法。 Joe Celko写了一本关于这个主题的书,你可能想看看。您可以通过Google在线获取大量示例。

答案 5 :(得分:1)

如果您可以迁移到SQL Server 2008并使用新的hiearchy数据类型。这个LINK启动了教程。使用hiearchy数据类型的代码更清晰。如果你不能使用2K8那么来自KM的父母/孩子就能很好地工作。