我正在电子商务网站上做一个项目,但我无法弄清楚如何为它设计数据库。在这个网站上,将有来自多个类别的产品,每个类别都有一套独特的过滤器。例如:笔记本电脑类别将有RAM,硬盘,显卡。衬衫类别过滤器的类型为Fabric类型等。
我想过两种方法,但我不确定应该使用哪种方式。
设计#1
categories
---------
id
category
filters (Here filters will be stored as hardcoded JSON)
products
--------
id
category_id
name
price
specifications (Stored as JSON which will be filters using values from categories.filters)
设计#2
categories
----------
id
category
table_name
products
--------
id
category_id
name
price
laptops
-------
id
product_id
ram
hard_disk
shirts
------
id
product_id
fabric
sleeve
我应该选择哪种设计?或者有更好的设计吗?
修改
这里我的问题不是关于多个类别。我在设计上遇到集成过滤器的问题。例如,如果我在笔记本电脑类别中检查RAM 4 GB,那么它应显示具有4 GB RAM的笔记本电脑类别的所有产品。我不能为每个过滤器或类别创建一个表,因为它们将超过100个。
答案 0 :(得分:1)
我会通过将整个目录视为树来解决您的问题,其中每条记录代表父类别和子类别/产品之间的关系。
产品:
+----+-----------+-----------+
| id | name | child_id |
+----+-----------+-----------+
| 1 | laptops | 2 |
| 1 | laptops | 6 |
| 2 | RAM | 3 |
| 2 | RAM | 4 |
| 2 | RAM | 5 |
| 3 | RAM - 1GB | null |
| 4 | RAM - 2GB | null |
| 5 | RAM - 4GB | null |
| 6 | hard disk | null |
| 7 | shirts | 8 |
| 8 | fabrics | null |
| 9 | desktops | 2 |
| 9 | desktops | 6 |
+----+-----------+-----------+
" root"类别是没有父母的类别。以下是查询所有根类别的方法:
SELECT DISTINCT(name)
FROM Products
WHERE id NOT IN (SELECT DISTINCT child_id FROM Products)
使用我的设计示例,这将分别为笔记本电脑,衬衫和桌面返回三个id值,分别为1,7和9。如果您想获得笔记本电脑的所有部件,您可以使用此查询:
SELECT child_id FROM Products WHERE id = 1
这将为RAM和硬盘类别返回2和6。您可以根据需要继续更深入地查询树。例如,如果您想获取所有RAM 产品,则可以执行以下查询:
SELECT id, name FROM Products WHERE id IN (3,4,5) AND child_id IS NULL
请注意使用IS NULL
来识别记录是产品而不是类别,因为它没有更多的孩子。
我相信即使在最深的情况下,即使是亚马逊和Overstock这样的大型电子商务网站也没有超过5-10级的层次结构。
答案 1 :(得分:1)
我正在关注@Tim Biegeleisen的设计,而不是把所有东西都放在一张桌子里。我将其修改为单独的类别,产品和过滤器。
categories
+----+----------+-----------+
| id | category | parent_id |
+----+----------+-----------+
| 1 | Computer | NULL |
+----+----------+-----------+
| 2 | Laptop | 1 |
+----+----------+-----------+
| 3 | Desktop | 1 |
+----+----------+-----------+
| 4 | Clothing | NULL |
+----+----------+-----------+
| 5 | T-Shirt | 4 |
+----+----------+-----------+
| 6 | Shirt | 4 |
+----+----------+-----------+
products
+----+-------------+-----------------+-------+
| id | category_id | name | price |
+----+-------------+-----------------+-------+
| 1 | 2 | Acer Aspire | 600 |
+----+-------------+-----------------+-------+
| 2 | 3 | Dell All-in-One | 750 |
+----+-------------+-----------------+-------+
| 3 | 6 | Lee Marc Shirt | 50 |
+----+-------------+-----------------+-------+
| 4 | 5 | Nike T-Shirt | 100 |
+----+-------------+-----------------+-------+
filters
+----+-------------+-----------------+------------+-------------+
| id | filter | value | product_id | category_id |
+----+-------------+-----------------+------------+-------------+
| 1 | RAM | 4 GB | 1 | 2 |
+----+-------------+-----------------+------------+-------------+
| 2 | Battery | Li-ion | 1 | 2 |
+----+-------------+-----------------+------------+-------------+
| 3 | HDD | 500 GB | 1 | 2 |
+----+-------------+-----------------+------------+-------------+
| 4 | RAM | 16 GB | 2 | 3 |
+----+-------------+-----------------+------------+-------------+
| 5 | HDD | 1 TB | 2 | 3 |
+----+-------------+-----------------+------------+-------------+
| 6 | Fabric | Cotton | 3 | 6 |
+----+-------------+-----------------+------------+-------------+
| 7 | Sleeve | Full | 3 | 6 |
+----+-------------+-----------------+------------+-------------+
| 8 | Size | M | 4 | 5 |
+----+-------------+-----------------+------------+-------------+
| 9 | Color | Black | 4 | 5 |
+----+-------------+-----------------+------------+-------------+
获取某个类别的所有过滤器:
SELECT DISTINCT `filters`.`filter` FROM `filters` WHERE `filters`.`category_id` = 2
了解笔记本电脑类别的所有可用内存大小:
SELECT DISTINCT `filters`.`value` FROM `filters` WHERE `filters`.`category_id` = 2 AND `filters`.`filter`='RAM'
可以排除category_id
表中的 filters
,因为我们可以从products
表中获取该值。我添加了它,因为每次我必须获得所有过滤器时,我都不必通过products
表。