关于表设计的思考
四种方案横向对比
| 方案 | 概述 | 代表平台 | 优点 | 缺点 |
|---|---|---|---|---|
| 方案一:元数据驱动 + 动态物理表 | 元数据定义结构,后台动态执行CREATE TABLE/ ALTER TABLE生成物理表。 | - OutSystems - Salesforce (部分实现) - JVS低代码平台 | - 查询性能高:利用物理表原生索引,性能最好。 - 维护直观:结构在数据库层面清晰可见。 - 事务支持强:完整支持ACID特性。 | - 扩展性差:增加租户/表单会产生海量表,元数据膨胀。 - DDL风险高:大量ALTER TABLE导致锁表,易引发DDL风暴。 - 并发支持弱:高并发下结构变更困难。 |
| 方案二:纯JSON列存储 | 所有业务数据存储在一张或多张表的单个JSON/JSONB列中,表结构固定。 | - MongoDB - Firebase - 部分轻量级低代码工具 | - 灵活性极高:无需预定义字段,可任意嵌套。 - 开发速度快:读写逻辑简单,类MongoDB的API丰富。 - 无DDL负担:彻底消除DDL操作。 | - 查询效率低:对JSON内部字段的查询和聚合性能有限,复杂JOIN困难。 - 事务支持弱:多数NoSQL跨文档事务能力有限。 - 运维成本高:存储空间放大,对DBA技能要求高。 |
| 方案三:固定核心表 + 行内JSONB(混合存储) | 一个“核心表”存放固定字段,一个“扩展表”存储动态字段,扩展表内用JSONB列存储所有动态属性。 | - 明道云 - 简道云 - NocoBase - Appsmith - Retool | - 平衡灵活与性能:高频查询走固定列,低频动态属性用JSONB。 - 避免DDL风险:扩展表的列是可变的,但结构固定。 - 支持查询:JSONB字段支持高效查询和部分索引。 | - 实现复杂度中等:需设计清晰的数据路由和查询转换逻辑。 - 查询有一定开销:跨表查询和JSONB内部条件查询比方案一略差。 - 元数据管理复杂:需维护一套映射关系。 |
| 方案四:冗余所有类型列(预先预留列) | 预先定义多个VARCHAR、INT等类型的列,将动态字段映射到这些物理列上。 | - 早期Salesforce (Flex Table) - 一些已淘汰的内部自研系统 | - 实现非常简单:物理表固定,应用逻辑直接。 - 规避DDL操作:字段增减不改变表结构。 - 与ORM集成好:可被多数ORM轻易映射。 | - 存储和行数浪费严重:多数预留字段为空,浪费空间,且直接限制总列数(如1024列)。 - 字段名无业务含义:VARCHAR_1,INT_2,维护和调试困难。 - 扩展性差:预留列总数有限,总有耗尽的一天。 |
方案三(混合存储)是综合来看最务实、最流行的选择。
- 原理:它将核心、高频查询的字段保留为物理列,而让大量动态、非核心字段进入JSONB扩展列。这样,既利用关系型数据库的强大查询能力保证了高性能,又获得了类似NoSQL的灵活性。
- 流行原因:该方案完美避开了方案一(DDL风暴)、方案二(查询弱)、方案四(空间浪费)的致命缺陷,同时在实现成本、未来扩展性、交付稳定性和查询性能之间取得了最佳平衡。
最终建议
- 采用方案一(动态物理表)作为核心架构,并用好 MySQL 8.0 Online DDL + gh-ost 规避风险。
- 允许在部分非核心表中使用 JSON 列(如操作日志、临时附件描述),但不作为主要数据存储方式。
- 绝对避免 EAV 模型(那篇文章对这一点是完全正确的)。
如果你决定走方案一,我可以继续提供:
- 基于 MyBatis-Plus 的动态建表/改表代码框架
- 元数据管理表设计(
entity_meta、field_meta) - gh-ost 集成到 Spring Boot 的自动化方案
- 满足等保审计的字段变更日志记录
MySQL 5.7 vs 8.0: 核心功能支持对比
| 功能维度 | MySQL 8.0 | MySQL 5.7 | 对方案一/方案三的影响 |
|---|---|---|---|
| 🔧 JSON支持 | 完整(含高性能函数) | 基础(仅基础函数) | 方案三性能与开发体验差距大 |
| ⚡ Online DDL | 5.6支持,5.7增强,更稳定 | 支持(仅允许“同时读写”) | 方案一加列、建索引可实现无锁变更 |
| 💣 原子DDL | 支持原子性 | 不支持原子性 | 方案一有数据不一致风险 |
| 📈 JSON 虚拟列索引 | 可在虚拟列上直接创建索引 | 需使用“存储列” | 方案三为高频字段加索引需增加存储开销 |
| 🚀 INSTANT ADD COLUMN | 支持 | 不支持 | 方案一加列会重建全表,大表执行缓慢 |
| 🔒 列级权限 | 支持 | 不支持 | 方案一无法实现字段级精细授权 |
| 🌐 角色(Role) | 支持 | 不支持 | 方案一权限管理更复杂 |
MySQL下载链接:直接从 MySQL 官方下载页面获取最新的社区版:https://dev.mysql.com/downloads/mysql/。
