【问题标题】:Tree structured database schema for Product categories产品类别的树状结构数据库架构
【发布时间】:2012-05-08 23:14:50
【问题描述】:

我正在为电子商务网站创建一个数据库,但我在产品类别的数据库架构方面遇到了问题,这有点像树状结构。

供应商可以属于一个或多个部门,部门可以有一个或多个类别,类别可以有一个或多个子类别。类似地,子类别可以有其子类别,依此类推...

产品应映射到供应商(如果部门未知)或部门(如果类别未知)或子类别等等。

做这种复杂关系数据库的最佳方法是什么。

【问题讨论】:

  • “最好”是什么意思?最容易存储,还是最快查询?
  • 我的意思是最快的查询以获得完整的层次结构可能在 xml 格式@StephaniePage

标签: sql database-design relational-database


【解决方案1】:

您可以在单个表中执行此操作。

ID  PARENT_ID   NAME
------------------------------
1   0           vendor1
2   0           vendor2
3   1           department11
4   1           department12
5   2           department21    
6   3           category11
7   6           subcategory11

从上面你可以了解整个...

【讨论】:

  • 这是一个非常简单的解决方案。我如何查询它以在 xml (MS SQL) 中给出树结构。如果您能给我提供查询,那就太好了..
  • 这是实现层次结构表结构的最佳方式,还是有更好的方式。在这种结构中保存部分很容易,但在检索时我们需要编写多个查询,例如要知道子类别 11 的供应商,我们需要通过查询顶部的每个级别来找到它。
  • 查询可能与此相关...create table YOUR_TABLE (id int(20) primary key, parent_id int(20) references YOUR_TABLE(id), name varchar2(100)); 是的,这是在树型数据库结构的情况下最喜欢的结构。
【解决方案2】:

我花了几天时间解决这个问题。

场景:

在以下领域销售绳索:配件、汽车 > 配件、船舶 > 配件

  • 有些绳索只在Marine > Accessories出售
  • 有些绳索只在配件中出售(顶部菜单项)
  • 部分绳索全部3个出售
  • 一般来说,任何项目都需要在任意数量的分支中列出,并且每个分支需要是任意可能的深度。 (此平台只允许 3 个,但为未来而设计)

Collections是某个商店平台允许人们组织物品的方式。 他们的字段是有限的,似乎只有标签字段可用于自定义信息。这是他们系统中离散项的逗号分隔字段。

以下是我的场景的 Collection ~~ 标准定义组合:

  • 配件~~标签=“配件”
  • 汽车 > 配件 ~~ tags = "汽车 > 配件"
  • 海洋 > 配件 ~~ tags = "海洋 > 配件"

我有一个包含 3 个类别的类别表:

Category_ID | Category_Text
 1             Accessories
 2             Automotive
 3             Marine

我卖 2 条绳子:汽车牵引绳通用尼龙绳

产品表:

Product_ID | Product_Title
 1            Automotive Tow-Rope 
 2            General Purpose Nylon Rope

我的数据提要带有一个类别字段,其中所有分支都以竖线分隔。

..., Title, Category, ...
..., "Automotive Tow-Rope",  "Automotive > Accessories", ...
..., "General Purpose Nylon Rope", "Accessories | Automotive > Accessories | Marine > Accessories", ...

我将 Category 字段拆分为像这样 Product_Category_Relationship 数据的关系表:

Product_ID | Branch | Level | Category_ID  (Showing text for clarity)
 1            1        1       2           (Automotive
 1            1        2       1                       + Accessories)
 2            1        1       1           (Accessories)
 2            2        1       2           (Automotive 
 2            2        2       1                       + Accessories)
 2            3        1       3           (Marine
 2            3        2       1                       + Accessories)

这样我可以看到多个分支,每个类别路径的深度。

此时我正在本地使用 SQL Server 来操作文件。我终于让这个查询以非规范化的方式将它们组合在一起。

*** TO DO: JOIN CATEGORY TABLE FOR ACTUAL TEXT VS CAT_ID LIKE EXAMPLE ***
SELECT prod_id,  STRING_AGG (branchpath,' | ') AS allpaths
FROM
    (SELECT prod_id, branch,  STRING_AGG (cat_id,',') WITHIN GROUP (ORDER BY depth) AS branchpath
    FROM prod_cat_rel
    GROUP BY prod_id, branch) t
GROUP BY prod_id

STRING_AGG 函数是最后的救命稻草。我也在其他平台上看到过关于类似功能的讨论,所以这不是 SQL Server 唯一的解决方案。

我尝试了很多方法将数据整理成合乎逻辑且灵活的排列,并且知道有些人会争论其他层次结构,但这对我有用。

很快,我将完成我的新商店并从我的网站链接它:C'mon 's GO! (cmonsgo.com)

我希望这对其他人有所帮助。 亚当

【讨论】:

    【解决方案3】:

    这是一个反复出现的问题。在纯 SQL 数据库中存储层次结构有两种常用方法(有些具有层次结构扩展,使其更容易)。

    第一个是@ketan 建议的解决方案。该模型的挑战在于,很难找到完整的子节点集 - 原生 SQL 不进行递归,因此“为供应商 x 找到所有子节点”可能很困难。

    替代方案是suggested by Joe Celko,通常称为“嵌套集”。 Wikipedia 上的例子很简单:

    Node        Left    Right
    Clothing    1   22
    Men's       2   9
    Women's     10  21
    Suits       3   8
    Slacks      4   5
    Jackets     6   7
    Dresses     11  16
    Skirts      17  18
    Blouses     19  20
    Ball Gowns  12  13
    Sun Dresses 14  15
    

    查找给定父母的所有孩子很容易:

    SELECT Child.Node, Child.Left, Child.Right
    FROM Tree as Parent, Tree as Child
    WHERE
        Child.Left BETWEEN Parent.Left AND Parent.Right
        AND Parent.Left = 1  -- Given Parent Node Left Index
    

    【讨论】:

      猜你喜欢
      • 2015-11-07
      • 1970-01-01
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多