Database design 在数据库中表示产品分类

Database design 在数据库中表示产品分类,database-design,tree,Database Design,Tree,我必须表示一个复杂的产品分类法,在数据库中具有父子关系。有人能指导我做这件事吗 例如,根可以是“所有产品” 然后可能在第二层,我们有“电脑”和“家具” 与树一样,每条记录都有一个父id。它引用同一表中的另一条记录 根元素的父id为NULL。 当然,最好将其编入索引 在某些用法中,将记录点指向其第一个直接同级是有效的。每条记录都有一个父id。它引用同一表中的另一条记录 根元素的父id为NULL。 当然,最好将其编入索引 在某些用法中,将记录点指向其第一个直接同级是有效的。下面是使用SQL Serv

我必须表示一个复杂的产品分类法,在数据库中具有父子关系。有人能指导我做这件事吗

例如,根可以是“所有产品” 然后可能在第二层,我们有“电脑”和“家具”
与树一样,每条记录都有一个父id。它引用同一表中的另一条记录

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


在某些用法中,将记录点指向其第一个直接同级是有效的。

每条记录都有一个父id。它引用同一表中的另一条记录

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


在某些用法中,将记录点指向其第一个直接同级是有效的。

下面是使用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\u 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)

下面是一个使用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\u 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)

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

在前一种情况下,一种结构可能是一组简单的表,如“product\u超类”、“product\u类和“product”。product_类可以具有product_类的外键,product可以具有引用product_类的外键

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


固定数量的级别可能会使查询更简单、更可读,但灵活性明显降低。

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

在前一种情况下,一种结构可能是一组简单的表,如“product\u超类”、“product\u类和“product”。product_类可以具有product_类的外键,product可以具有引用product_类的外键

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

固定数量的级别可能会使查询更简单、可读性更强,但灵活性明显降低。

对于您提出的问题,没有一个“最佳”答案

您可能希望避免陷入单独表(两个或更多)中的父/子关系中,因为事情几乎马上就变得一团糟

考虑使用更通用的“Product”表,并允许它引用父值(另一个产品记录的ID)

最好对此进行一点建模-

但它可以分为“结构”、“产品(样式)”,然后是SKU(有库存的可销售商品)随着时间的推移,SKU有时会进一步细分为UPC(EAN),具体取决于产品类型(例如,杂货店为SKU提供多个UPC,用于季节性轮换)

注意-然后可以根据适当的ID将属性分配到任何级别,突然您可以访问这些属性进行继承

对于你提出的问题,没有一个“最佳”答案

您可能希望避免陷入单独表(两个或更多)中的父/子关系中,因为事情几乎马上就变得一团糟

考虑使用更通用的“Product”表,并允许它引用父值(另一个产品记录的ID)

最好对此进行一点建模-

但它可以分为“结构”、“产品(样式)”,然后是SKU(有库存的可销售商品)随着时间的推移,SKU有时会进一步细分为UPC(EAN),具体取决于产品类型(例如,杂货店为SKU提供多个UPC,用于季节性轮换)


注意-然后可以根据适当的ID将属性分配到任何级别,突然您可以访问这些属性进行继承

在SQL中有许多不同的方法来管理树。乔·塞尔科就这个话题写了一整本书,你可能想看看。你可以在网上搜索大量的例子。

在SQL中有许多不同的方法来管理树。乔·塞尔科就这个话题写了一整本书,你可能想看看。如果您可以转到SQL Server 2008并使用新的层次结构数据类型,您可以在线搜索大量示例。

。这将开始教程。使用分层数据类型的代码要干净得多。如果您不能使用2K8,那么KM中的父级/子级运行良好。

如果您可以移动到SQL Server 2008并使用新的层次结构数据类型。这将开始教程。使用分层数据类型的代码要干净得多。如果您不能使用2K8,则KM的父/子系统运行良好。

但这不是一个很好的设计示例。没有键或RI,所有列都可以为空。@dportas,我说过
简单树示例
。这提供了对这个问题更好的基本理解,而不仅仅是建议“谷歌”搜索这个主题(就像你在回答中所做的那样:)。这不是一个很好的设计示例。没有键或RI,所有列都可以为空。@dportas,我说过
简单树示例
。这比仅仅建议“谷歌”搜索主题(就像你在回答中所做的那样:)提供了对这个问题更好的基本理解。感谢所有在这个主题上提供帮助的人谢谢所有在这个主题上提供帮助的人