1

我正在尝试重构和规范 MySQL 中的产品表,如下所示:

CREATE TABLE `products` (
`id` varchar(45) NOT NULL, # alphanumeric product codes
`productCategory` varchar(45) NOT NULL, 
`productSubCategory` varchar(45) DEFAULT NULL, 
`productRange` varchar(45) NOT NULL,
`productClass` varchar(45) DEFAULT NULL,
`name` text NOT NULL,
`size` int(11) NOT NULL,
`sizeMeasure` varchar(5) NOT NULL,
`boxQuantity` int(11) NOT NULL,
`sellingPrice` double NOT NULL,
`rrp` double DEFAULT NULL,
`ordinalValue` int(11) NOT NULL,
PRIMARY KEY (`id`)
)

我认为需要重构的是productCategory,productSubCategoryproductRange字段。这样做的原因是我需要能够获得类别的层次结构。还计划将元数据添加到类别中。

表字段当前包含以下数据:

productCategory     productSubCategory      productRange
---------------------------------------------------------
retail              retail_solution1        retail_solution1_range1
retail              retail_solution2        retail_solution2_range2
retail              retail_solution3        retail_solution3_range3
professional        prof_solution1          prof_solution1_range1
professional        prof_solution1          prof_solution1_range2
professional        prof_solution1          prof_solution1_range3
professional        prof_solution2          prof_solution2_range1
professional        prof_solution2          prof_solution2_range2
professional        prof_solution2          prof_solution2_range3
...                 ...                     ...

本质上,在productCategoryRETAIL 集中,productSubCategoryproductRange字段具有相同的VARCHAR(45)值。

这棵树的深度在未来极不可能发生变化。最常见的更改可能是类别名称。

我查看了邻接表和嵌套集模型,不知何故感觉更倾向于使用嵌套集模型。


到目前为止,我对嵌套集模型方法的了解是:

该模型

添加类别:

CREATE PROCEDURE `addCategory`(IN parent VARCHAR(45), IN child VARCHAR(45))
BEGIN
    SELECT @myLeft := lft FROM product_category

    WHERE name = parent LIMIT 1;

    UPDATE product_category SET rgt = rgt + 2 WHERE rgt > @myLeft;
    UPDATE product_category SET lft = lft + 2 WHERE lft > @myLeft;

    INSERT INTO product_category(name, lft, rgt) VALUES(child, @myLeft + 1, @myLeft + 2);
END

删除类别:

CREATE PROCEDURE `deleteCategory`(IN name VARCHAR(45))
BEGIN
    SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
    FROM product_category
    WHERE name = name;

    DELETE FROM product_category WHERE lft BETWEEN @myLeft AND @myRight;

    UPDATE product_category SET rgt = rgt - @myWidth WHERE rgt > @myRight;
    UPDATE product_category SET lft = lft - @myWidth WHERE lft > @myRight;
END

我想在 java web 应用程序中使用 sql,而不是存储过程。我正在使用 Spring 的JDBCTemplate所有数据访问。目前我不确定如何处理这个问题,因为我之前没有使用过多语句查询JDBCTemplate

理想情况下,我还想使用 DBUnit 测试数据访问层。

让我对这个项目感到失望的是,不知何故,我觉得需要更加重视顶级类别。也许 RETAIL 和 PROFESSIONAL 的顶级类别应该是产品类型而不是类别?

任何指导将不胜感激。谢谢。

4

1 回答 1

0

oh well, this looks ugly.

Firstly you should use category-ids to store them into your product (and not varchars), next I would use a simple hirarchical setup of the categories itself.

If you can only have two levels ( the product is either in the root category itself, or in one of its subcategories ) Simply do something like:

categoryID, name, parentId:
1, sports, NULL
2, Crossbows, 1
3, Golf, 1
4, Healthcare, NULL

Here sports and Healthcare are "master" level, as your Retail and Professional would be.

if you can have a deeper structure, I would consider using a different approach, since multi-level hirarchy is a pain in the arse in most databases, espec. in mysql (oracle has CONNECT BY PRIOR command against/for this)

If this is the case, I would store the fullpath in a string like an OS would (root/subcat1/subcat2...), this can get somehow sticky, when something is updated, but is very fast on retrival instead of the full recursive retrival of hirarchies.

Another topic that discussed this retrival problem How to do MySQL Looped Join which tests if results are complete? (with codes required)

After you resolved your category to a ID, simply store the specific (and only) id in the product itself as a foreign key.

于 2012-09-03T11:17:49.217 回答