知识卡片

EAV模式在MySQL下特别不适用:受61张表关联上限约束

普通读书笔记卡

内容

实体-属性-值(EAV)设计模式——用一张通用表把”实体ID、属性名、 属性值”三列存起来,以此避免为每种实体单独建一张固定字段的表—— 本身在任何关系数据库里都算不上好设计,但在MySQL下会额外撞上 一堵具体的墙:MySQL对单次关联操作有一个硬性限制,最多只能 关联61张表。EAV模式的查询模式天然依赖大量自关联(要把同一张 EAV表按不同属性反复关联自身,才能拼出一个实体的完整属性 视图),这种查询模式很容易触及甚至超过这个61张表的上限—— 而这不是配置项能调整的,是MySQL这个具体实现里的硬编码限制。 更值得注意的是,即使关联表数还没到61张表这个硬上限,MySQL 在解析和优化查询时的开销本身也会随着关联表数量的增加而显著 上升,书中给出一条经验法则:如果希望查询执行得快、并发性好, 单个查询最好把关联控制在12张表以内。这说明EAV这类”通用schema” 设计的风险不是抽象的”理论上不优雅”,而是会具体撞上MySQL这一 特定实现的两道门槛:一道是61张表的硬性上限(撞上直接报错), 另一道是12张表左右开始明显下降的查询优化效率(撞上是逐渐 变差、不会立刻报错,因此更容易被忽视)。选择schema设计模式 时,不能只看它在抽象关系模型层面是否成立,还要核实具体数据库 实现对这种模式所依赖的操作(这里是大量自关联)是否有硬性 限制。

参考来源

- 位置:《高性能MySQL:第3版》第4章"Schema与数据类型优化"4.2节 "MySQL schema设计中的陷阱"(源文件: _epub-src/OEBPS/Text/part0011.xhtml) - 结论依据:原文明确"MySQL限制了每个关联操作最多只能有61张表, 但是EAV数据库需要许多自关联。我们见过不少EAV数据库最后超过了 这个限制。事实上在许多关联少于61张表的情况下,解析和优化 查询的代价也会成为MySQL的问题。一个粗略的经验法则,如果希望 查询执行得快速且并发性好,单个查询最好在12个表以内做关联", 直接给出EAV模式在MySQL下面临的硬性表数上限与查询优化效率 经验法则两道门槛。 - 原始内容:MySQL限制了每个关联操作最多只能有61张表,但是EAV 数据库需要许多自关联。我们见过不少EAV数据库最后超过了这个 限制。