EAV(Entity-Attribute-Value,实体-属性-值)模型是一种用来存储稀疏、动态属性的数据建模方式。查询 EAV 表通常比普通关系表复杂,下面我用常见场景 + 示例 SQL来说明。
假设有三张表:
-- 实体表
entities (
id INT PRIMARY KEY,
name VARCHAR(100)
)
-- 属性表
attributes (
id INT PRIMARY KEY,
attr_name VARCHAR(100)
)
-- 值表(EAV核心)
entity_values (
entity_id INT,
attribute_id INT,
value VARCHAR(255)
)
SELECT
a.attr_name,
ev.value
FROM entity_values ev
JOIN attributes a ON ev.attribute_id = a.id
WHERE ev.entity_id = 1;
例如:查询 color = red 的实体
SELECT ev.entity_id
FROM entity_values ev
JOIN attributes a ON ev.attribute_id = a.id
WHERE a.attr_name = 'color'
AND ev.value = 'red';
例如:color = red 且 size = M
SELECT ev.entity_id
FROM entity_values ev
JOIN attributes a ON ev.attribute_id = a.id
WHERE (a.attr_name = 'color' AND ev.value = 'red')
OR (a.attr_name = 'size' AND ev.value = 'M')
GROUP BY ev.entity_id
HAVING COUNT(DISTINCT a.attr_name) = 2;
SELECT
ev.entity_id,
MAX(CASE WHEN a.attr_name = 'color' THEN ev.value END) AS color,
MAX(CASE WHEN a.attr_name = 'size' THEN ev.value END) AS size,
MAX(CASE WHEN a.attr_name = 'price' THEN ev.value END) AS price
FROM entity_values ev
JOIN attributes a ON ev.attribute_id = a.id
GROUP BY ev.entity_id;
如果你用的是 MySQL 5.7+ / PostgreSQL:
SELECT
entity_id,
JSON_OBJECTAGG(a.attr_name, ev.value) AS attrs
FROM entity_values ev
JOIN attributes a ON ev.attribute_id = a.id
GROUP BY entity_id;
SELECT
entity_id,
jsonb_object_agg(a.attr_name, ev.value) AS attrs
FROM entity_values ev
JOIN attributes a ON ev.attribute_id = a.id
GROUP BY entity_id;
✅ 给 entity_values(entity_id, attribute_id) 加联合索引
✅ 属性尽量少、热数据可冗余到主表
✅ 复杂查询优先用「宽表 / JSON」
✅ 大数据量场景考虑 列式存储或文档数据库
❌ 属性固定且查询频繁
❌ 需要大量聚合、排序
❌ 强事务一致性要求
如果你能告诉我:
我可以给你更精准的 SQL。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。