1

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

我遇到的问题,也许我只是没有想清楚,是他们的类别信息可以是 3-6 个子类别的深度;总是至少有 2 个类别(顶级父类别和更具体的子类别),但根据项目最多可以有 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 级(ecdb2_lvl_3 ) 但对于没有第 3 级的项目,它从第 2 级开始显示。正如您从架构中看到的那样,它们将所有内容放在一个表中,该表列出了产品及其所属的所有类别,而不是像自引用类别表和连接产品表之类的东西。

问题是有些项目只有 2 个级别,有些像这个有多达 4 个,还有一些有全部 6 个 - 供应商的示例网站,可在http://www.biggestbook.com很好地完成了我想要的工作,但我无法访问他们的代码,所以我对他们究竟是如何拉回类别并遍历它们感到摸不着头脑。我假设他们有某种全局标志来指示您当前所处的级别(例如,办公用品为 1,信封为 2,等等),因此他们可以跟踪您当前的深度,并且然后检查每个子级别,看看是否有更多的子类别要显示,但是当我想到如何有效地处理这个问题时,我是在画一个空白。他们的命名方案也有很多不足之处,但如果需要,我可以稍后解决。

有人对如何解决这个问题有建议吗?我计划在 C#/ASP.NET 中存储(可能是 MVC,可能不是),所以 C# 示例将是最有用的,但我可以很容易地遵循大多数语言来弄清楚。

4

1 回答 1

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 是 2 级类别,则没有 3 级类别的产品将首先出现,因为在排序时 null 排在最前面。

附带说明一下,他们会跟踪您在会话中遍历了哪些类别以到达产品。跟随一个类别到一个产品,直到 URL 显示类似 ?R=12345 的内容。面包屑将显示用于查找该产品的类别。清除 cookie 并刷新页面,面包屑将变成最大的书 > 产品详细信息。这对于从搜索引擎访问该页面的人来说并不是非常有用,因为他们无法轻松地选择一个类别来查看有哪些类似的产品可用。

于 2009-01-15T15:45:48.460 回答