EAV(Entity-Attribute-Value,实体-属性-值)模型因为在关系型数据库里把“列”变成了“行”,所以索引设计非常关键,否则查询会非常慢。下面从原理到实践讲清楚怎么建索引。
最常见结构:
CREATE TABLE eav_values (
entity_id BIGINT,
attribute_id INT,
value VARCHAR(255),
PRIMARY KEY (entity_id, attribute_id)
);
或者更通用的:
CREATE TABLE eav_values (
id BIGINT AUTO_INCREMENT,
entity_id BIGINT,
attribute_id INT,
value_type VARCHAR(20),
value_str VARCHAR(255),
value_num DECIMAL(18,4),
value_date DATETIME,
PRIMARY KEY (id)
);
最常见查询:
WHERE entity_id = ? AND attribute_id = ?
✅ 索引:
CREATE INDEX idx_entity_attr ON eav_values(entity_id, attribute_id);
如果是多值表,直接把它设为主键更好。
例如:
WHERE attribute_id = 1 AND value = 'active'
✅ 索引:
CREATE INDEX idx_attr_value ON eav_values(attribute_id, value);
⚠️ 顺序很重要:
attribute_idvalue例如:
WHERE attribute_id = 5 AND value_num > 100
✅ 索引:
CREATE INDEX idx_attr_num ON eav_values(attribute_id, value_num);
日期同理:
CREATE INDEX idx_attr_date ON eav_values(attribute_id, value_date);
value 用单一索引❌ 错误:
CREATE INDEX idx_value ON eav_values(value);
原因:
比如:
拆成普通列:
CREATE TABLE users (
id BIGINT,
status VARCHAR(20),
price DECIMAL(10,2),
created_at DATETIME
);
EAV 只存“真正动态的字段”。
✅ 这是生产环境最常用的优化手段。
定期把 EAV 转成宽表:
user_id | status | price | tags
查询直接走宽表索引。
CREATE TABLE entities (
id BIGINT,
attrs JSON
);
CREATE INDEX idx_attrs ON entities((attrs->>'status'));
比纯 EAV 快得多。
| 查询场景 | 推荐索引 |
|---|---|
| entity + attribute | (entity_id, attribute_id) |
| attribute + value | (attribute_id, value) |
| attribute + 数值 | (attribute_id, value_num) |
| attribute + 时间 | (attribute_id, value_date) |
| 热点属性 | 拆列 / 宽表 |
如果你愿意,可以告诉我:
我可以直接帮你设计最优索引方案。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。