数据库是网站后台的根基,表结构一旦上线就很难大改。很多项目后期维护痛苦,根源都在于前期设计不规范——表名一会儿驼峰一会儿下划线、字段类型随意定、该建索引的没建、该拆表的揉在一起。本篇梳理尧图建站团队沉淀的数据库设计规范,帮你从源头避免这些坑。
一、命名规范的统一原则
命名规范的核心是"统一"二字,具体用什么风格反在其次。在尧图,我们约定:库名、表名、字段名全部小写,单词之间用下划线分隔(snake_case);表名用复数或加业务前缀,如 cms_article、sys_user;字段名用单数,如 title、add_time。
统一前缀能大幅提升可读性。常见做法是按模块加前缀:sys_ 表示系统表(用户、角色、权限)、cms_ 表示内容表(文章、栏目、分类)、log_ 表示日志表。一眼就能看出某张表属于哪个业务域,排查问题时效率倍增。
- 主键统一命名为
id,bigint 无符号自增。 - 时间字段统一
create_time/update_time,用 datetime。 - 布尔字段用
is_前缀,如is_deleted,类型 tinyint(1)。 - 外键字段用
目标表单数_id,如user_id、category_id。
二、字段类型与主键设计
字段类型的选择直接影响存储空间和查询性能。原则是"够用就好,不要贪大"。状态、性别这类枚举值用 tinyint 而非 int;金额用 decimal(10,2) 而非 float(浮点数有精度问题);短文本用 varchar 并限定长度,长文本用 text;时间统一 datetime,避免 timestamp 的 2038 限制和时区坑。
CREATE TABLE cms_article (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
category_id INT UNSIGNED NOT NULL COMMENT '分类ID',
title VARCHAR(120) NOT NULL COMMENT '标题',
author VARCHAR(32) NOT NULL DEFAULT '' COMMENT '作者',
content MEDIUMTEXT NULL COMMENT '正文',
view_count INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '阅读量',
is_deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
create_time DATETIME NOT NULL COMMENT '创建时间',
update_time DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_category (category_id),
KEY idx_create (create_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章表';
主键设计上,推荐自增整型而非 UUID。自增主键占 8 字节、按序写入利于 B+ 树页填充、范围查询高效;UUID 占 16 字节、随机写入导致页分裂频繁、性能明显下降。如果必须用分布式 ID,可以用雪花算法生成有序的 64 位整数,兼顾唯一性与有序性。
三、索引与范式的取舍
索引是双刃剑,加速查询但拖慢写入。建索引的判断标准是:出现在 WHERE、ORDER BY、JOIN 条件里的高频字段才建。单表索引数量建议不超过 5 个,且优先建联合索引而非多个单列索引——联合索引遵循"最左前缀"原则,能覆盖多种查询组合。
-- 联合索引:能命中 (a) (a,b) (a,b,c) 三种查询
ALTER TABLE cms_article ADD INDEX idx_cat_status_time(category_id, is_deleted, create_time);
范式方面,企业官网这类中等规模系统,不必死守第三范式。适当反范式(在文章表冗余分类名称、在订单表冗余商品名)能减少 JOIN、提升查询速度,付出的代价只是少量存储空间和更新时的同步成本。原则是"读多写少的字段可以冗余,频繁变动的字段必须关联"。
最后,软删除(is_deleted)字段会让表越来越大、索引越来越慢,建议定期归档历史数据到冷表,保持热表精简。这些规范一旦在项目初期确立并坚持,整个后台的数据层会清爽很多。