处理变量类别层次结构

时间:2009-01-15 14:53:45

标签: database-design e-commerce

我遇到的问题如下:我公司的供应商为我们提供了一个Access数据库(我导入到SQL Server中),其中包含了他们的产品信息(另一种方法是使用XML),我试图将其按下来更适用于电子商务网站的格式。

我遇到的问题,也许我只是没有想清楚,他们的类别信息可以是3-6个子类别的深度;总是至少有两个类别(顶级父类别和更具体的子类别),但根据项目最多可以有6个。

他们的数据在下表结构中提供给我:

CREATE TABLE [dbo].[ECDB2_HIERARCHY](
    [SEQ_ID] [int] NOT NULL,
    [PFX_NUM] [nvarchar](3) NOT NULL,
    [STK_NUM] [nvarchar](12) NOT NULL,
    [ECDB2_LVL_1] [nvarchar](max)  NULL,
    [ECDB2_LVL_1_ID] [int] NULL,
    [ECDB2_LVL_2] [nvarchar](max) NULL,
    [ECDB2_LVL_2_ID] [int] NULL,
    [ECDB2_LVL_3] [nvarchar](max) NULL,
    [ECDB2_LVL_3_ID] [int] NULL,
    [ECDB2_LVL_4] [nvarchar](max) NULL,
    [ECDB2_LVL_4_ID] [int] NULL,
    [ECDB2_LVL_5] [nvarchar](max) NULL,
    [ECDB2_LVL_5_ID] [int] NULL,
    [ECDB2_LVL_6] [nvarchar](max) NULL,
    [ECDB2_LVL_6_ID] [int] NULL

在大多数情况下,我可以忽略SEQ_ID,因为它没有被使用; PFX_NUM和STK_NUM连接在一起形成产品的SKU,但这不是问题。我需要能够从网站动态遍历类别。例如,给定以下行:

SEQ_ID: 364867 (ignored)

PFX_NUM: AMP

STK_NUM: 73121

ECDB2_LVL_1: Office Supplies

ECDB2_LVL_1_ID 11

ECDB2_LVL_2: Envelopes, Mailers & Shipping Supplies

ECBD2_LVL_2_ID: 26

ECDB2_LVL_3: Envelopes

ECDB2_LVL_3_ID: 195

ECDB2_LVL_4: Business Letter Envelopes

ECDB2_LVL_4_ID: 795

ECDB2_LVL_5: (empty)

ECDB2_LVL_5_ID: 0

ECDB2_LVL_6: (empty)

ECDB2_LVL_6_ID: 0

用户应该能够浏览各个级别,但是让我失望的是提供数据的示例网站(见下文)以随机的间隔显示子类别下的所有项目...它看起来像是在第3个level(ecdb2_lvl_3)但是对于没有第3级的项目,它从第2级开始显示。从模式中可以看出,它们将所有内容放在一个表中,列出了产品及其所属的所有类别,而不是类似自引用类别表和连接产品表。

问题在于某些项目只有2个级别,有些项目最多有4个级别,还有一些项目全部有6个级别 - 供应商的示例网站,可在http://www.biggestbook.com处获得良好的工作我想要什么,但我无法访问他们的代码,所以我不知道他们究竟是如何撤回类别并遍历它们的。我假设他们有某种全局标志来表明你目前处于什么级别(例如1个用于Office Supplies,2个用于Envelopes等等),这样他们就可以跟踪你当前的深度,以及然后检查每个子级别以查看是否有更多的子类别要显示,但是当我想到如何有效地处理这个时,我正在画一个空白。他们的命名方案也有很多不足之处,但如果需要,我可以稍后解决这个问题。

任何人都有关于如何解决这个问题的建议?我在C#/ ASP.NET(可能是MVC,可能不是)中规划商店,所以C#示例最有用,但我可以轻松地使用大多数语言来解决它。

1 个答案:

答案 0 :(得分:0)

如果您不介意使用递归函数遍历自引用类别表,请务必重新设计数据库以转到该路径。有人会认为SQL中的递归函数可能是性能自杀,但如果设置了适当的索引,它可以非常快速地完成。

对于您正在使用的数据集,您可以从示例网站上看到他们在URL查询中存储当前类别:

办公用品>信封,邮寄和信封运送用品>信封
?N = 4294858589&安培; ...

办公用品>信封,邮寄和信封运送用品>信封>小册子&目录信封
?N = 4294858588&安培; ...

其中N是当前类别。我认为他们的数据库有一个查找表来查看N所属的级别。或者,他们可能正在做一个大的WHERE / ORDER BY子句,如:

WHERE (ECDB2_LVL_1_ID == @N) OR (ECDB2_LVL_2_ID == @N) OR (ECDB2_LVL_3_ID == @N) ...
ORDER BY ECDB2_LVL_1_ID, ECDB2_LVL_2_ID, ECDB2_LVL_3_ID...

如果N是第二级别类别,那么没有第三级别类别的产品将首先出现,因为在排序时,null会出现在顶部。

在旁注中,他们会跟踪您在会话中访问产品的类别。按照类别下载到产品,直到URL说出类似的内容?R = 12345。面包屑将显示用于查找该产品的类别。清除您的Cookie并刷新页面,面包屑将变成Biggest Book>产品明细。这对于从搜索引擎访问该页面的人来说并不是非常有用,因为他们无法轻松选择类别以查看可用的类似产品。