我有以下数据库结构:
[CATEGORY]
category_id
parent(default 0)
title
[PRODUCT]
product_id
title
[PRODUCT_TO_CATEGORY]
product_id
category_id
CATEGORY 的示例数据:
1 0 TV
2 1 PLASMA
3 1 LED
. . ...
PRODUCT 的示例数据:
1 Sony
2 Sharp
3 Samsung
. ...
PRODUCT_TO_CATEGORY 的示例数据:
1(Sony) 1(TV)
2(Sharp) 2(PLASMA)
3(Samsung) 2(PLASMA)
首先,我想问一下我的结构是否良好。例如,我应该为每个产品分配类别和子类别ID,还是单个类别运作良好?
然后根据假设每个产品属于一个类别而一个类别可能有父母或更多,我如何检索当前和每个子类别的产品?
例如,打电视类别应该列出索尼,夏普和三星,而不仅仅是索尼项目。
答案 0 :(得分:1)
父级(默认为0)
使用NULL而不是0.这将允许您使用正确的FOREIGN KEY(如下图所示)。
我应该为每个产品分配类别和子类别ID
你不应该。只需指定适用于该产品的最具体的子类别。所有超类别都可以从CATEGORY
表中定义的层次结构中推断出来,因此在产品中存储(甚至一个)它们是多余的。
出于性能原因,这种冗余有时可能是合理的,但是您必须使用数据一致性来平衡它们。在这种情况下,没有良好的声明方式来保持冗余数据与“主”数据同步 - 您必须通过触发器或(上帝禁止)应用程序代码来执行此操作,并且您可能会在此过程中引入并发错误,除非你仔细考虑你的锁定策略非常非常。
然后基于假设每个产品属于一个类别......
此假设使您的模型不正确。要正确建模此N:1关系,您不需要联结表PRODUCT_TO_CATEGORY
,只需在产品和类别之间使用外键:
注意:如果您想允许无类别的产品(即您的关系实际上是N:0..1而不是N:1),请使PRODUCT.CATEGORY_ID
为空。
您的数据如下:
CATEGORY:
1 TV NULL
2 PLASMA 1
3 LED 1
PRODUCT:
1 Sony 1 (TV)
2 Sharp 2 (PLASMA)
3 Samsung 2 (PLASMA)
如何检索当前和每个子类别的产品?
首先识别属于所需“子树”的所有类别,然后检索连接到它们的产品。在这种情况下,搜索所有电视可以这样做:
获取您要搜索的“热门”类别的ID:1(电视)。
SELECT CATEGORY_ID FROM CATEGORY WHERE TITLE = 'TV'
获取所有子类别的ID:2(PLASMA)和3(LED)。
SELECT CATEGORY_ID FROM CATEGORY WHERE PARENT_ID IN (1)
重复步骤(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不支持那种允许你在单个数据库往返中完成所有操作的递归查询。
答案 1 :(得分:0)
了解用于分组产品的嵌套集。 http://en.wikipedia.org/wiki/Nested_set_model
它允许您在关系数据库中创建一个漂亮的结构,以将产品分配给类别。比大多数人提出的典型的孩子 - >父母模型要好得多。