我目前正在重新设计一个负载较重的网站,如果您对特定数据库设计问题有任何意见,我将不胜感激。
这个概念是在数据库中保存许多产品(其中 500K)。 每个产品都可以有多个动态属性(大约 1K),并且每个属性都有多个预定义但动态的值(假设每个属性平均有 10 个,因此大约 10K)
此时这是简化的数据库结构:
产品(产品表)
+--------+--------------+
| ProdID | Product Name |
+--------+--------------+
| 1 | T-Shirt XYZ |
+--------+--------------+
| 2 | Dress ABC |
+--------+--------------+
| ... | ... |
+--------+--------------+
| 500000 | Something |
+--------+--------------+
属性定义(属性表)(它保存属性类型)
+--------+--------------+
| PropID | Property Name|
+--------+--------------+
| 1 | color |
+--------+--------------+
| 2 | size |
+--------+--------------+
| ... | ... |
+--------+--------------+
| 100 | Some Prop |
+--------+--------------+
属性值定义(值表)
+-----------+--------+-------+
| PropValID | PropID | Value |
+-----------+--------+-------+
| 1 | 1 | red |
+-----------+--------+-------+
| 2 | 1 | blue |
+-----------+--------+-------+
| 3 | 2 | m |
+-----------+--------+-------+
| 4 | 2 | xl |
+-----------+--------+-------+
| 5 | 2 | xxl |
+-----------+--------+-------+
| ... | ... | ... |
+-----------+--------+-------+
| 1000 | 100 | xyz |
+-----------+--------+-------+
这样我们就可以在任何产品中添加任意数量的属性和值。 下表包含此信息。
产品属性和值(ProdPropVal 表)
+--------+--------+--------+-----------+
| InfoID | ProdID | PropID | PropValID |
+--------+--------+--------+-----------+
| 1 | 1 | 1 | 1 |
+--------+--------+--------+-----------+
| 2 | 1 | 2 | 3 |
+--------+--------+--------+-----------+
| 3 | 2 | 1 | 2 |
+--------+--------+--------+-----------+
| 4 | 2 | 2 | 5 |
+--------+--------+--------+-----------+
| ... | ... | ... | |
+--------+--------+--------+-----------+
在上面的示例中,我们知道“T-Shirt XYZ”为蓝色,尺寸为中等。
现在是棘手的部分...... 如果我们想找到具有共同属性值集的所有产品(所有蓝色和中等尺寸的产品),哪种方法是最好的方法?
我的想法:
在 ProdPropVal 表中搜索一次每个 PropValID 并在代码中比较结果。这可以通过从最罕见的 PropValID 开始并在下一个查询中使用 WHERE ProdID IN(先前的 ID)限制 ProdID 来进行微调。
在 ProdPropVal 表中为每个所需的 PropValID 使用内部联接。类似于: SELECT ProdID FROM ProdPropVal ppv1 INNER JOIN ProdPropVal ppv2 ON ppv1.ProdID = ppv2.ProdID INNER JOIN ProdPropVal ppv3 ON ppv1.ProdID = ppv3.ProdID INNER JOIN ProdPropVal ppv4 ON ppv1.ProdID = ppv4.ProdID其中 ppv1.PropValID = 10和 ppv2.PropValID = 20 和 ppv3.PropValID = 30 和 ppv4.PropValID = 150
到目前为止,这些是我的想法。 ProdPropVal 平板电脑拥有数百万行,这一事实不会留下任何出错的空间。
非常欢迎任何建议!
最佳答案
要查找所有蓝色和中等尺寸的产品,我会这样做:
SELECT ProdID
FROM ProdPropVal
WHERE (PropID = 1 AND PropValID = 2)
OR (PropID = 2 AND PropValID = 3)
GROUP BY ProdID
HAVING COUNT(*) = 2
更好的是,如果 PropValID 在 Values 表中是唯一的,那么您可以从 ProdPropVal 表中删除 PropID 列,并将查询简化为:
SELECT ProdID
FROM ProdPropVal
WHERE PropValID IN (2, 3)
GROUP BY ProdID
HAVING COUNT(*) = 2
关于MySQL 数据库 - 性能设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6399181/