2013-02-15 75 views
1

我有以下的数据库结构:获得从子类SQL查询项目

[CATEGORY] 
category_id 
parent(default 0) 
title 

[PRODUCT] 
product_id 
title 

[PRODUCT_TO_CATEGORY] 
product_id 
category_id 

示例数据类别

1 Sony 
2 Sharp 
3 Samsung 
. ... 

1 0 TV 
2 1 PLASMA 
3 1 LED 
. . ... 

产品的样本数据

示例数据为PRODUCT_TO_CATEGORY

所有我想问如果我的结构良好的
1(Sony) 1(TV) 
2(Sharp) 2(PLASMA) 
3(Samsung) 2(PLASMA) 

第一。例如,我应该将类别和子类别ID分配给每个产品,还是一个类别工作良好?

然后根据每个产品属于一个类别的假设和一个类别可能有一个或多个父类,我如何检索当前和每个子类别的产品?
例如,打电视类别应列出索尼,夏普和三星,而不只是索尼项目。

+0

不可以。您不会在产品中嵌入父/子。这可能会导致加入不良关系的可能性,例如(“游戏控制台”,“戴尔”)或(“创新公司”,“微软”)。仅嵌入一个类别,从中检索相关联的父项很麻烦。 – 2013-02-15 14:29:47

回答

1

父(默认为0)

使用NULL而不是0这将允许你使用正确的外键(如下图所示)。


我应该既类别和子类别的ID分配给每个产品

你不应该。只分配适用于该产品的最具体的子类别。所有超类别都可以从CATEGORY表中定义的层次结构中推断出来,因此在产品中存储(甚至是其中之一)是多余的。

由于性能原因,有时候这样的冗余是有道理的,但是你必须在数据一致性之间进行平衡。在这种情况下,没有很好的声明方法来保持冗余数据与“主”数据同步 - 您必须通过触发器或(上帝禁止)应用程序代码来完成此操作,并且您可能会引入并发错误,除非你认真考虑你的锁定策略非常,非常非常非常非常


然后基于属于一个类别每个产品的假设......

这个假设让你的模型不正确。为了这款N正确型号:1间的关系,你并不需要结合表PRODUCT_TO_CATEGORY,你只需要产品和类别之间的外键:

enter image description here

注意:请在PRODUCT.CATEGORY_ID为空的,如果你想允许无类别的产品(即你的关系实际上是N:0..1而不是N:1)。

而且你的数据会看起来像:

CATEGORY: 

1 TV  NULL 
2 PLASMA 1 
3 LED  1 

PRODUCT: 

1 Sony 1 (TV) 
2 Sharp 2 (PLASMA) 
3 Samsung 2 (PLASMA) 

我怎么可以检索产品当前和每一个孩子类别?

首先识别属于所需“子树”的所有类别,然后检索连接到它们的产品。在这种情况下,所有的电视搜索可以做这样的:

  1. 获得“顶”类别您正在搜索的ID:1(TV)。

    SELECT CATEGORY_ID FROM CATEGORY WHERE TITLE = 'TV'

  2. 获取所有的子类别的ID:2(血浆)和3(LED)。

    SELECT CATEGORY_ID FROM CATEGORY WHERE PARENT_ID IN (1)

  3. 重复步骤(2),直到你到达的层次结构的“底部”:

    SELECT CATEGORY_ID FROM CATEGORY WHERE PARENT_ID IN (2, 3)

    上面的查询将返回一个空的结果对你的榜样的数据集,所以你会知道你可以停下来。在更复杂的层次结构中,您可能需要多次重复上述查询,始终用最近检索到的“层”类别替换IN列表。

    如果您碰巧在数据中有循环,请小心无限循环!获取连接到任何已识别类别的所有产品:1(TV),2(PLASMA)和3(LED)。

    SELECT * FROM PRODUCT WHERE CATEGORY_ID IN (1, 2, 3)

不幸的是,MySQL不支持那种递归查询的,它会让你做的一切,在一个单一的数据库往返。

0

阅读有关用于分组产品的嵌套集。 http://en.wikipedia.org/wiki/Nested_set_model

它允许您在关系数据库中创建一个很好的结构,以将产品分配给类别。比大多数人提出的典型的儿童 - >父母模型好得多。

+0

有趣。但是当你让管理员为用户创建这些类别时,我不明白为什么要使用这种技术。类别和子类别不是固定的,而是CMS的一部分,看起来这种技术的更新和计算可能是一团糟.. – mallix 2013-02-17 12:18:58

+0

您可以轻松地为用户创建用户界面以创建/管理类别,然后使用该类别映射产品做法。这是非常好的,因为你可以将一个产品映射到父类别,而不是所有的孩子。您还可以将一个产品映射到子类别,并自动显示在所有父母身上。我已成功地将它用于_with_用户分配给在线拍卖网站,该网站将产品映射到类别。 – ryan1234 2013-02-18 00:53:46