我正在尝试重构和规范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
,productSubCategory
和productRange
字段。原因是我需要能够获得类别的层次结构。它还计划在类别中添加元数据。
表字段当前包含如下数据:
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
... ... ...
基本上在productCategory
零售集中,productSubCategory
和productRange
字段具有相同的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的顶级类别应该是产品类型而不是类别?
非常感谢任何指导。感谢。
答案 0 :(得分:0)
首先,您应该使用category-id将它们存储到您的产品中(而不是varchars),接下来我将使用类别本身的简单hirarchical设置。
如果您只能有两个级别(该产品位于根类别本身或其子类别中) 只需执行以下操作:
categoryID, name, parentId:
1, sports, NULL
2, Crossbows, 1
3, Golf, 1
4, Healthcare, NULL
在这里,体育和医疗保健是“主要”级别,就像您的零售和专业人士一样。
如果你可以拥有更深层的结构,我会考虑使用不同的方法,因为在大多数数据库中,多级层次结构是一种痛苦。在mysql中(oracle对此有CONNECT BY PRIOR命令)
如果是这种情况,我会将完整路径存储在一个像操作系统那样的字符串中(root / subcat1 / subcat2 ...),当某些内容更新时,这可能会有点粘性,但反向速度非常快hirarchies的完全递归回顾。
讨论此追溯问题的另一个主题How to do MySQL Looped Join which tests if results are complete?(需要代码)
将类别解析为ID后,只需将产品本身的特定(且唯一)ID存储为外键即可。