数据库容量规划需提前预判膨胀趋势、识别高增长表、设分层预警阈值并建自动化清理归档机制;典型信号包括3月内行数增超300%、TEXT/BLOB滥用、频繁加非空字段、索引冗余及avg_row_length异常上升。

数据库容量规划不是等磁盘快满了才去管的事,而是要提前预判表结构膨胀趋势、识别高增长表、设置合理预警阈值,并建立自动化的清理与归档机制。
识别表结构膨胀的典型信号
表结构本身不会“膨胀”,但实际使用中因设计或业务变化导致数据量激增、索引冗余、字段类型不合理,会引发存储异常增长。常见信号包括:
- 同一张表在3个月内行数增长超300%,但业务量无对应突增
- TEXT/BLOB字段被大量写入,且未做内容截断或外存分离
- 频繁添加新字段(尤其非空+无默认值),导致ALTER TABLE锁表时间变长、碎片率升高
- 索引数量超过5个,且存在重复前缀(如 idx_user_id 和 idx_user_id_status)
- avg_row_length持续上升,但业务逻辑未变更——可能因VARCHAR长度被设为最大值(如65535)却只存几个字符
用SQL快速定位高增长表和空间占用大户
不同数据库语法略有差异,以MySQL为例,可执行以下查询:
查近7天增长最快的表:
SELECT table_name, ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb, ROUND(data_free / 1024 / 1024, 2) AS free_mb, table_rows FROM information_schema.tables WHERE table_schema = 'your_db_name' AND table_type = 'BASE TABLE' ORDER BY (data_length + index_length) DESC LIMIT 10;
查索引冗余(需配合pt-duplicate-key-checker或手动分析):重点关注相同前导列的复合索引,例如(user_id, status) 和 (user_id, status, created_at),后者通常可覆盖前者。
磁盘空间预警的实用阈值与响应动作
不要等磁盘使用率到95%才报警。建议分层设置:
- 80% → 告警通知DBA:触发人工检查,确认是否为临时导入/日志堆积,查看innodb_data_file_path或pg_wal目录是否异常增长
- 85% → 自动冻结非关键写入:如关闭用户注册、暂停报表生成任务(通过应用配置开关或数据库级READ_ONLY=ON)
- 90% → 强制启动清理流程:执行预定义的TRUNCATE旧分区、删除3个月前日志表、压缩BLOB字段(转为外部存储+URL引用)
- 95% → 只读保护+短信强提醒:防止误操作写入,同时通知运维扩容或迁移冷数据
注意:预警应基于可用空间绝对值(如剩余<50GB),而非单纯百分比,避免小磁盘过早误报、大磁盘延迟响应。
长期防膨胀的结构优化习惯
从源头减少无序增长:
- 新建表禁用TEXT/BLOB,改用VARCHAR(255) + 外部对象存储(如S3/OSS),业务层控制上传大小
- 时间字段统一用DATETIME(3)或TIMESTAMP,避免用BIGINT存毫秒时间戳(占8字节且无法直接索引范围查询)
- 枚举类字段用TINYINT或ENUM(MySQL)或DOMAIN(PostgreSQL),不用VARCHAR(20)
- 所有大表必须按时间或业务ID做范围/列表分区,且定期DROP旧分区(非DELETE)
- 每季度执行一次ANALYZE TABLE + OPTIMIZE TABLE(仅MyISAM或低频更新InnoDB),或PostgreSQL的VACUUM FULL(慎用)










