EAV(Entity-Attribute-Value,实体-属性-值)模型是一种用于应对高度动态、稀疏属性结构的数据建模方式(典型场景:商品属性、医疗病历、自定义表单)。
由于它的结构特点,对索引设计有非常特殊的要求,核心目标是:避免全表扫描、支持按属性筛选、支持聚合分析。
典型 EAV 表结构:
entity_id | attribute_id | value
或
entity_id | attribute_id | value_string | value_number | value_datetime
特点:
(attribute_id, value) 组合索引这是最重要、最基础的索引。
CREATE INDEX idx_attr_value
ON eav (attribute_id, value);
✅ 用途:
SELECT entity_id
FROM eav
WHERE attribute_id = 101
AND value = 'red';
⚠️ 单独索引 attribute_id 或 value 都不够。
entity_id(顺序很关键)如果查询是:
推荐:
(attribute_id, value, entity_id)
✅ 好处:
如果 EAV 拆成:
eav_string
eav_int
eav_date
那么每个表都需要:
(attribute_id, value)
❌ 不要在一个 value 列里混类型(索引效率极差)
EAV 表本身只是“属性附件”,实体主表必须有:
entity(id PK)
entity(type, status, created_at)
并建索引:
(type, status)
(created_at)
否则:
“查某类实体 + 某属性” 依然慢
例如:
SELECT entity_id FROM eav WHERE attribute_id=101 AND value='red';
SELECT entity_id FROM eav WHERE attribute_id=102 AND value='L';
在代码中取交集。
✅ 简单
❌ 属性多时性能下降
entity_id | color | size | price
对常用查询建索引:
(color, size)
✅ 查询极快
❌ 牺牲灵活性
❌ 只在 entity_id 上建索引
❌ 在 value 上建单列索引
❌ 用 LIKE 查 EAV(无法走索引)
❌ 期望 EAV 像宽表一样快
| 数据库 | 建议 |
|---|---|
| MySQL | 拆类型表 + 组合索引 |
| PostgreSQL | JSONB + GIN(替代传统 EAV) |
| Oracle | 函数索引 / 物化视图 |
| ES | 直接当 EAV 用 |
EAV 模型对索引的要求是:以“属性 + 值”为核心建立组合索引,并配合实体主表索引和宽表/搜索引擎来缓解多属性查询性能问题。
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。