数据库开发规范
涵盖 MySQL、ClickHouse、Redis 三类数据存储的开发约束。 标注【强制】为必须遵守,【建议】为推荐遵守。
目录
1. MySQL 规范
1.1 建表规范
| 级别 | 规则 |
|---|---|
| 【强制】 | 第一列必须是主键,非特殊场景默认使用自增主键(聚簇索引特性) |
| 【强制】 | 存储引擎使用 InnoDB |
| 【强制】 | 字符集使用 utf8mb4,COLLATE 使用 utf8mb4_general_ci(建表时指定) |
| 【强制】 | 字段定义为 NOT NULL(NULL 导致索引、统计、值计算更复杂,占用更多存储空间) |
| 【强制】 | 小数类型使用 decimal,禁止使用 float 和 double |
| 【建议】 | decimal 字段根据精度需求选择规格:常规场景 decimal(27,10),高精度场景(如链上资产)decimal(40,18) |
| 【强制】 | 库、表、字段名统一小写,必须加注释 |
| 【强制】 | 不允许使用外键、存储过程、视图(维护麻烦,迁移升级易出错,性能差) |
| 【建议】 | 单表索引数量 < 8,索引内字段 < 5(索引过多影响插入更新效率) |
| 【建议】 | 长度 > 60 的字段添加索引时,使用前缀索引:ADD KEY (column_name(prefix_length)) |
| 【建议】 | 索引字段区分度 > 0.6(COUNT(DISTINCT 列名) / COUNT(*),区分度越高性能越好) |
| 【建议】 | 索引命名:普通索引 idx_xxx,唯一索引 uniq_xxx |
| 【建议】 | 字段、表名、别名禁止使用 MySQL 关键字 |
1.2 SQL 规范
| 级别 | 规则 |
|---|---|
| 【建议】 | 用 is_deleted 伪删除代替 DELETE |
| 【强制】 | 禁止跨库访问表资源 |
| 【强制】 | WHERE 条件严格按照字段类型,字符串类型必须加引号 |
| 【强制】 | WHERE 条件必须能走索引(用 EXPLAIN 验证) |
| 【强制】 | 禁止使用 ORDER BY RAND() |
| 【强制】 | 禁止表达式方式检索数据(如 1 + column_name = 5) |
| 【强制】 | 超过三张表禁止 JOIN;JOIN 字段数据类型必须一致;被关联字段必须有索引 |
| 【建议】 | 禁止使用 SELECT * |
| 【建议】 | ORDER BY 和 GROUP BY 的字段需要是索引字段 |
| 【强制】 | 表名字段名使用反引号 ` 包裹,避免碰到 MySQL 保留字 |
| 【建议】 | 尽量使用 JOIN 代替子查询 |
1.3 IDE 工具规范
| 级别 | 规则 |
|---|---|
| 【强制】 | 使用正版软件 |
| 【推荐】 | DataGrip(收费)或 MySQL Workbench(官方开源) |
| 【强制】 | 禁止使用 Navicat 破解版(曾被发现存在漏洞,有泄露数据库账号密码风险) |
1.4 公共字段规范
所有业务表必须包含以下公共字段:
CREATE TABLE `xxx` (
`xx_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
-- ⚠️ 主键禁止直接使用 id,应参考表名命名(如 order_id, user_id)
`user_id` BIGINT UNSIGNED NOT NULL DEFAULT '0' COMMENT '用户ID',
`channel_id` INT UNSIGNED NOT NULL DEFAULT '101' COMMENT '渠道ID',
`i18n_lang` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '多语言字段标签',
`create_time` BIGINT UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间(Unix时间戳)',
`update_time` BIGINT UNSIGNED NOT NULL DEFAULT '0' COMMENT '更新时间(Unix时间戳)',
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`xx_id`),
UNIQUE KEY `uniq_channel_user_id` (`channel_id`, `user_id`), -- 唯一索引 uniq_
KEY `idx_create_time` (`create_time`) -- 普通索引 idx_
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='xxx表';
要点:
- 主键命名:DDL 层使用
{表名缩写}_id,不要用id;Go struct 中框架约定使用id,通过 xorm tag 映射:xorm:"'xx_id' pk autoincr" - 时间双写:
create_time/update_time(后端程序维护,Unix 时间戳,业务查询用)+created_at/updated_at(数据库维护,timestamp 默认值,运维排查用),两者都必须保留 - 索引命名:唯一索引
uniq_,普通索引idx_
2. ClickHouse 规范
2.1 使用场景
ClickHouse 仅用于数据分析类需求,满足以下条件时使用:
- 很少或没有 UPDATE/DELETE(< 10次/秒)
- 大数据量宽表聚合查询
- 低 QPS 场景(< 100)
- 无事务一致性需求
2.2 建表规范
| 级别 | 规则 |
|---|---|
| 【强制】 | 字段不允许为 NULL |
| 【强制】 | 库、表、字段名统一小写,必须加注释 |
| 【建议】 | 表需要有时间字段做分区 |
| 【强制】 | 除特殊需求,存储引擎使用 MergeTree |
| 【强制】 | 主键应选择分布均匀且查询最频繁的字段 |
2.3 命名规范
| 对象 | 规则 | 示例 |
|---|---|---|
| 库/表/字段 | 统一小写,加注释(同 MySQL) | analytics.user_events |
| 分区字段 | 使用 dt 或 event_date | PARTITION BY toYYYYMM(dt) |
| 物化视图 | 前缀 mv_ | mv_daily_user_stats |
| 普通索引 | 前缀 idx_(同 MySQL) | idx_user_id |
2.4 开发规范
| 级别 | 规则 |
|---|---|
| 【强制】 | 禁止使用 SELECT * |
| 【强制】 | 禁止 3 表以上 JOIN;多表 JOIN 时必须满足小表在右原则(右表被加载到内存与左表比较) |
| 【强制】 | 禁止使用点查(CK 的稀疏索引使得 KV 类型查询性能不佳,不要当关系型数据库用) |
| 【建议】 | 尽量用物化视图代替 JOIN(高性能) |
| 【建议】 | INSERT 尽量批量进行(单次 INSERT > 1000 条) |
3. Redis 规范
3.1 架构设计
| 级别 | 规则 |
|---|---|
| 【强制】 | Redis 版本 > 6.0 |
| 【强制】 | 开启 activedefrag,主动碎片清理(config set activedefrag yes) |
| 【建议】 | 单实例容量限制在 10GB 以内(超过 10GB 做 RDB 时间增长,fork 影响业务,底层 rehash 增加影响) |
| 【建议】 | 禁止产生 BigKey:String 大小 ≤ 100KB;List/Hash/Set/ZSet 元素数量 ≤ 1W(大 key 可拆分为多个小 key) |
| 【强制】 | 禁止紧密重试(重试时间增加 1-10ms 随机值) |
| 【强制】 | Key 名字不超过 16KB |
| 【强制】 | 危险命令屏蔽:KEYS(可能堵塞)、FLUSHDB/FLUSHALL(删库)、DEL 大 key(堵塞,改用 UNLINK,要求 Redis ≥ 4.0) |
3.2 Key 命名规范
格式:{业务}:{模块}:{标识}
| 示例 | 说明 |
|---|---|
user:session:12345 | 用户会话 |
order:lock:67890 | 订单分布式锁 |
cache:product:list:page1 | 商品列表缓存 |
alarm:lock:{md5} | 告警去重 key |
jwt:12345:{jti} | JWT 双验证 key |
规则:
- 使用冒号
:分隔层级(Redis 客户端友好) - 全小写,禁止空格和特殊字符
- 业务前缀必须明确,禁止无前缀裸 key
- 临时 key 加
tmp:前缀
3.3 开发规范
| 级别 | 规则 |
|---|---|
| 【强制】 | 所有 key 必须设置过期时间;批量写入 key 设置随机过期时间(防止大批量 key 同时过期造成雪崩) |
| 【建议】 | 渐进式处理:分批查询/写入,单次不超过 1000 个元素或 10KB(避免流量过大造成压力) |
| 【强制】 | Pipeline 单次请求不超过 200 个(过多会阻塞 Redis 服务、打满带宽) |
| 【建议】 | 不要用 Redis 做队列(使用 Kafka、MQ 等专用组件替代) |
版本:v0.0.1 | 最后更新:2026-03-10 | 维护人:Tom