EAV(Entity-Attribute-Value,实体-属性-值)模型本质上是用行代替列来存异构属性,因此“宽表稀疏”(大量 NULL 列)的问题在 EAV 中天然被规避了;但 EAV 自己也会带来另一种稀疏/低效问题:
所以“避免稀疏”通常指两件事:避免存储稀疏 和 避免查询/使用时的逻辑稀疏。下面分层说。
传统宽表:
user(id, name, height, blood_type, favorite_brand ...)
多数用户只填部分字段 → 大量 NULL。
EAV:
entity_attr(entity_id, attr_id, value)
只存“有值的属性”,没有值就不插入行。
✅ 存储上不稀疏。
查询一个实体全部属性时:
SELECT attr_id, value
FROM eav
WHERE entity_id = 1;
结果是“竖表”,业务代码还要拼。
规避:
SELECT entity_id,
JSON_OBJECTAGG(attr_id, value)
FROM eav
GROUP BY entity_id;
EAV 常把 value 存成 VARCHAR,导致:
规避:
value_string, value_int, value_datetime, value_decimal
如果 80% 实体都有 name / status / created_at
→ 放 EAV 是过度设计。
规避(混模):
这是生产中最常见做法。
WHERE attr='age' AND value>30
AND attr='city' AND value='BJ'
容易写成多次 JOIN。
规避:
GROUP BY + HAVING 代替多 JOINuser(id, attrs JSONB)
EAV 不是用来“避免稀疏”的银弹,而是用来“支持无限属性”的妥协方案。
最佳实践:
如果你愿意,可以告诉我:
我可以直接给你表结构设计示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。