我必须在数据库中表示具有父子关系的复杂产品分类。有人可以指导我这么做吗?
例如根可能是'所有产品' 然后可能在第二级我们有'电脑'和'家具' 像一棵树??
答案 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的父母/孩子就能很好地工作。