如何在mysql EAV模型中实现数据过滤

时间:2015-09-15 09:11:49

标签: mysql sql database rdbms entity-attribute-value

我在mysql的EAV模型中创建了一个表格我最大的问题是如何像电子商务网站一样进行数据过滤让我展示一些数据以及我真正想要实现的目标

我有一个名为value的表,我有四列

id product_id  Attribute_name Attribute Value
1     1          Brand           Apple
2     1          Model           Iphone6
3     1          Color           White
4     1           OS             ios

5     2          Brand           Samsung
6     2          Model           Note4
7     2          Color           Black
8     2          OS              Android 

9     2          Brand           SONY
10    2          Model           Xperia
11    2          Color           Red
12    2          OS              Android 

我要创建所有4个过滤表,假设有人检查苹果和三星然后只有两个模型必须出现Iphone6和Note4然后当用户检查Iphone6时只有白色和操作系统中的ios出现如何做到这一点请我解决这个问题非常糟糕2天

1 个答案:

答案 0 :(得分:0)

更改您的表格结构,以便BrandModelColorOS属性可以让生活更轻松,但假设有一个很好的理由让您可以'转换它,我推荐一个嵌套查询:

SELECT * FROM value WHERE product_id = (
     SELECT product_id
     FROM value
     WHERE Attribute_name = 'Brand'
     AND Attribute_value = 'Apple'
);

这将返回与Apple产品相关的所有信息。如果要过滤该列表以便获得模型列表,请将条件附加到外部查询,例如:

SELECT * FROM value WHERE product_id = (
     SELECT product_id
     FROM value
     WHERE Attribute_name = 'Brand'
     AND Attribute_value = 'Apple'
)
AND Attribute_name = 'Model';

这里有一个很好的分析EAV模型的优缺点: https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model#EAV_versus_row_modeling

如果要拉出多个匹配项,可以OR将嵌套查询放在一起:

SELECT * FROM value WHERE product_id = (
     SELECT product_id
     FROM value
     WHERE Attribute_name = 'Brand'
     AND Attribute_value = 'Apple'
) OR product_id = (
     SELECT product_id
     FROM value
     WHERE Attribute_name = 'Brand'
     AND Attribute_value = 'Samsung'
)
AND Attribute_name = 'Model';

如果你想在多个级别拉多个匹配,你可以继续嵌套堆栈:

SELECT * FROM value WHERE product_id = (
     SELECT product_id
     FROM value
     WHERE Attribute_name = 'Brand'
     AND Attribute_value = 'Apple'
) OR product_id = (
     SELECT product_id
     FROM value
     WHERE Attribute_name = 'Brand'
     AND Attribute_value = 'Samsung'
)
AND Attribute_name = 'Model'
AND (Attribute_value = 'iPhone' OR Attribute_value = 'S3');