
简介数据库设计规范V1.0文档是一份面向数据库设计人员与开发团队的规范资料可用于统一项目中的命名规则和操作流程。文档细化区分了物理结构对象与逻辑结构对象并给出数据库、日志、配置文件、表空间、索引等对象的命名示例同时明确SQL脚本操作、注释备查、数据字典先行等数据库维护原则适合软件研发团队在项目设计或维护阶段对照使用。包体仅包含1个doc文件大小约135KB内容是完整的规范正文共涵盖目的、范围、术语、设计概要、命名规范逻辑对象、数据库对象命名、脚本注释、数据库操作原则、常用字段命名参考等章节。已有273人学习下载。对于正在制定团队数据库设计规范或希望提升库表可维护性的学习者可直接获得一份具备实操约束的V1.0规范模板可用于对照优化自身项目降低沟通与后期维护成本。1. 一份“3数据库设计规范.doc”盯着看三分钟不如动手修一张表接手别人的项目第一件事往往不是看代码而是先翻那份“3数据库设计规范.doc”。打开一看表名规则、字段类型、索引要求都写得明明白白再回头看线上库一半表没按它来。这种场景太常见了问题不在规范本身写得不好而在规范没落成可执行的检查动作。这篇就围绕这类数据库设计规范doc文档把从文档到库表的落地路径完整拆开规范里的硬规矩怎么理解怎么照着生成建表SQL怎么用扫描脚本做评审以及最容易翻车的几个点。适合正打算定规范或接手旧库的开发与DBA也适合刚被要求“按规范改表”又不知道从哪下手的人。2. 规范文档里的硬规矩命名、字段类型、索引三张底线2.1 命名规范表名、字段名的前缀后缀不是审美问题大多数规范doc第一章节就是命名但真正执行到位的不多。常见做法是表名采用三段式业务域缩写2到4位加下划线加业务对象再加可选后缀。比如订单域的表写成ord_order_info、ord_order_item支付域写成pay_payment_record。字段名统一小写加下划线分词动词在前名词在后create_time、update_time、del_flag这类字段全公司一个口径不要一半写created_at一半写gmt_create。参数上要注意两点一是业务域缩写要有登记表防止两个人各编各的二是保留字清单必须附在规范文档里order、group、desc这类词一旦落到字段名里所有SQL都要带反引号脏数据就是这么来的。索引命名也有约定普通索引用idx_加表名缩写加字段名唯一索引用uk_开头这样在慢查询日志里一眼能看出索引用途。我一般还会在规范里加一条硬性要求字段名不允许出现大小写混用。MySQL在Linux下对表名区分大小写开发环境Mac不区分Windows更不区分同一套建表脚本在两个环境跑出来的结果不一样。这种问题用规范文档约束比用代码审查更前置也更好说服人。2.2 字段类型选型不是“哪种对”是“哪种出事少”字段类型这一节是规范doc里被翻得最多的地方也是执行时争议最大的地方。核心原则是能用精确类型就别用近似类型能用定长就别用变长能放整数就别放字符串。场景推荐类型不推荐类型原因主键 / 订单号BIGINT UNSIGNEDINTINT上限21亿订单量稍大就爆金额DECIMAL(10,2)FLOAT / DOUBLE浮点精度会导致对账不平业务编号CHAR(定长)VARCHAR定长无碎片等值查询更快状态 / 枚举TINYINTVARCHAR减小索引体积避免脏值时间DATETIMETIMESTAMPTIMESTAMP到2038年溢出真伪布尔TINYINT(1)CHAR(1)语义清晰排序无歧义金额字段用DECIMAL(10,2)是我在很多规范里看到的标准写法但要注意这个精度上限是99999999.99接近一亿。如果你的业务订单量可能达到这个量级要写DECIMAL(14,2)而不是等爆了再改。字符串长度是另一个重灾区VARCHAR(255)是默认兜底但索引列不建议超过64个字符否则联合索引的长度会迅速顶到上限。规范文档里最好把常见字段列一张表用户名VARCHAR(64)、手机号CHAR(11)、邮箱VARCHAR(128)、地址VARCHAR(255)让开发不用自己想。2.3 索引设计在规范文档里最容易被抄错的三条索引章节在doc里通常很长但真正起作用的往往就三条硬规则。第一条是联合索引要遵守最左前缀(user_id, create_time)这个索引能走user_id的条件也能走两者的范围但单独查create_time走不了。很多人把最常用的字段放最后等于白建。第二条是覆盖索引查询列都包含在索引里可以避免回表这也是为什么规范里强调不要用SELECT *多出来的字段会直接破坏覆盖索引的效果。第三条是隐式转换问题。字段类型是VARCHAR但传入参数是数字或者字段是DATETIME但传入字符串MySQL可能放弃索引做全表扫描。规范里要写明应用层传参类型必须与字段类型严格一致日期传字符串也统一格式。区分度太低的列不要建索引比如del_flag只有0和1两个值建了索引优化器也不走还白占空间和写入开销。判断区分度最简单的方法是SELECT COUNT(DISTINCT col) / COUNT(*) FROM table低于0.1就不建议建单列索引。3. 把doc规范落成建表SQL一张业务表的DDL模板和必调参数3.1 一张订单表的DDL模板先套模板再谈优化规范文档写得再好最后都要落到一条CREATE TABLE上。我一般会在规范里附一张标准DDL模板开发照模板改业务字段就行不用每次重新想规则。以订单信息表为例MySQL 8.0的建表语句长这样CREATE TABLE ord_order_info ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键ID, order_no CHAR(32) NOT NULL COMMENT 订单编号全局唯一, user_id BIGINT UNSIGNED NOT NULL COMMENT 用户ID, total_amount DECIMAL(14,2) NOT NULL DEFAULT 0.00 COMMENT 订单总金额单位元, status TINYINT NOT NULL DEFAULT 0 COMMENT 订单状态0待支付1已支付2已取消, del_flag TINYINT NOT NULL DEFAULT 0 COMMENT 逻辑删除0未删除1已删除, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_order_info_order_no (order_no), KEY idx_order_info_user_id_create_time (user_id, create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci COMMENT订单信息表;这段模板里有几个参数属于“动了就会出事”的类型。引擎写死InnoDB不要给开发留讨论空间MyISAM在并发写入和崩溃恢复上都不适合业务表。字符集统一utf8mb4排序规则选utf8mb4_0900_ai_ciMySQL 8.0默认或utf8mb4_general_ciMySQL 5.7常用为什么不用utf8因为utf8在MySQL里最多3字节存不了emoji也会在某些生僻字上报错。每个字段都带COMMENT表和字段没有注释的表后面维护的人只能靠猜。3.2 主键、外键、唯一约束规范里写得最多也最容易吵的三件事主键选型在团队里吵得最凶。自增主键写起来简单但在分库分表、数据迁移、异构同步场景下非常痛苦两个库的数据合并时主键直接冲突。分布式ID雪花算法、号段模式没有这个问题但规范文档要写清楚使用条件单表单库且没有合并诉求用自增没毛病预见到分片或迁移主键业务化成BIGINT并注明ID生成方式。不管哪种主键类型必须BIGINT UNSIGNED这是无数个爆表事故换来的教训。外键算是规范文档里最微妙的点。多数互联网公司规范写着“禁止物理外键”因为外键会让插入和更新都去检查关联表在高并发下锁竞争明显分库分表后外键直接失效。但“禁止物理外键”不等于“不要逻辑外键”规范要同时写明所有逻辑外键字段比如user_id必须在子表建索引否则父表删数据时子表查询会全表扫。唯一约束我只要求用在做业务唯一校验上比如order_no、支付流水号不要拿唯一约束当普通索引用二者语义完全不同。3.3 建表后的自检清单五分钟检查十三个点规范文档落成DDL模板还不够要有一个建表后自查清单开发写完表自己先过一遍再提交评审。我常年在用的清单有十三条引擎是否为InnoDB。字符集是否为utf8mb4排序规则是否与库一致。每张表是否有表注释。每个字段是否有注释。主键是否命名id类型是否BIGINT UNSIGNED。是否存在预留字段field1、remark1这种一律打回。金额字段是否用DECIMAL精度是否符合业务量级。逻辑删除字段是否统一命名del_flag且默认0。所有索引命名是否带idx_或uk_前缀。是否存在重复索引比如单列索引和联合索引首列重复。时间字段是否统一为DATETIME。字段名是否命中保留字清单。枚举字段是否用TINYINT并注明每个值含义。这份清单可以直接做进表格每条对应“判定标准”和“违规示例”评审时逐条勾。它能省掉相当一部分来回打回的沟通成本因为开发自己先用清单过滤过一遍提上来的表结构已经基本合规了。4. 用规范做评审十项检查单加information_schema扫描4.1 评审检查单从规范文档抽出的十项硬指标评审不能对着doc一条条念要先把规范文档转成可勾选的检查单。我平时会把规范压缩成十项硬指标评审只看这十项过不过其余的建议项让团队自己讨论检查项判定标准违规示例处置方式表命名业务域前缀一致无保留字order_info缺前缀打回重命名字段命名下划线分词无大小写混用orderNO打回重命名主键BIGINT UNSIGNED自增或分布式IDINT类型主键必须修改金额DECIMAL且精度足够FLOAT金额必须修改字符集utf8mb4统一单表latin1必须修改注释表、字段全有注释业务字段无注释补充逻辑删除字段名del_flag默认0用status9表示删除统一保留字不命中MySQL保留字desc、rank重命名时间字段DATETIME或TIMESTAMP统一字符串存时间必须修改索引命名规范、无冗余、逻辑外键有索引无索引的user_id补索引评审时要逐条记录结论不能只写“过了”或“打回”要写明对应规范文档的章节号。这样后续追责或复盘时有据可查不会变成口头争论。4.2 用SQL查询information_schema核对全库表结构人工检查单能管新表存量老表还是要靠扫描。information_schema是MySQL自带的元数据库所有表结构信息都在这用几条SQL就能把不合规的表捞出来。第一条是找非InnoDB引擎的表SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA your_db AND ENGINE InnoDB;这条SQL的结果如果任何一行说明库里存在旧引擎表要么转引擎要么迁移。TABLE_SCHEMA记得替换成实际库名如果一次要扫多个库把TABLE_SCHEMA your_db改成TABLE_SCHEMA NOT IN (mysql, information_schema, performance_schema, sys)即可。第二条是找没有主键的表SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.TABLES t WHERE TABLE_SCHEMA your_db AND NOT EXISTS ( SELECT 1 FROM information_schema.STATISTICS s WHERE s.TABLE_SCHEMA t.TABLE_SCHEMA AND s.TABLE_NAME t.TABLE_NAME AND s.INDEX_NAME PRIMARY );没有主键的表在复制和日志同步场景下会有很大隐患binlog模式切到ROW后无主键表的更新操作会全表扫描定位行。第三条是找字符集不是utf8mb4的表SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA your_db AND TABLE_COLLATION NOT LIKE utf8mb4%;这三条SQL建议做成一个存储过程或脚本每月跑一次结果直接发到群里。别等到出事了再回头查存量库的规范问题越拖越难收拾。4.3 评审记录怎么回填到doc评审结果要回填到规范文档本身这一步做得好的团队不多。每次评审后把争议点和结论追加到doc的“评审记录”章节格式是日期、表名、违反条款、处置结果。比如“2025-03-14pay_refund表违反3.2.1金额字段精度要求已修改并重新评审”。doc本身没有版本对比能力所以变更记录必须人工维护这是规范文档能持续活下来的关键。5. 数据库设计规范落地避坑五个翻车现场和排查方法5.1 翻车字段类型按规范写了线上还是爆表现象订单表刚过千万级查询突然变慢看慢查询日志全是主键查询。排查发现主键虽然是BIGINT UNSIGNED但业务订单号字段设计成了VARCHAR(64)所有按order_no查询的接口都走全表扫描。原因规范只说了订单号要建唯一索引没规定类型和长度开发用了字符串拼接的订单号。解决规范里把订单号这类业务标识符的类型写死为CHAR(32)或BIGINT并给这条单独加“必选”标记。如果线上已经出问题先加前缀索引缓解再排期改字段。5.2 翻车索引建了查询还是不走路现象明明按规范建了idx_user_id_create_time实际查询EXPLAIN出来typeALL。原因有两类一是查询条件写了WHERE user_id ? AND create_time LIKE %2025-03%LIKE以%开头导致索引失效二是应用层传参时把user_id当字符串传字段是BIGINT发生隐式转换。解决规范文档增加一条“索引列禁止前置模糊和函数包裹”代码评审时用EXPLAIN抽查慢查询发现LIKE %...直接改写成范围查询。5.3 翻车表结构完全合规批量导入还是慢到离谱现象新表严格按照规范建了五六个索引初始化数据时用程序一条条插入几十万条数据跑了几个小时。原因每条插入都要同步更新所有索引自增主键还导致写入集中在最后一页加上事务逐条提交性能必然垫底。解决批量导入场景先按规范建好表但导入前ALTER TABLE ... DISABLE KEYS关掉非唯一索引导入完成后ENABLE KEYS重建。注意唯一索引不能用这个方式关得靠INSERT ... ON DUPLICATE KEY UPDATE或先清理重复数据。规范文档里补一句数据初始化不走应用层逐条插入用LOAD DATA INFILE或分批提交。5.4 翻车评审过了半年后表结构没人敢动现象一张表经历过三次需求变更字段加了十几个索引加了七八个现在改任何一个字段都要讨论半天。原因评审只看了建表初稿没有管后续变更字段和索引越堆越多没人知道哪些是废弃的。解决规范文档增加“表结构变更流程”任何字段变更都要提交变更脚本和回滚脚本评审时同步审查冗余索引。用一条SQL查冗余索引联合索引的前缀列与单列索引重复每季度清理一次SELECT TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA your_db GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME HAVING COUNT(*) 1 AND MIN(COLUMN_NAME) IN ( SELECT SUBSTRING_INDEX(GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX), ,, 1) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA your_db GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME HAVING COUNT(*) 1 );5.5 翻车规范文档更新了开发还在用旧版现象规范文档从第2版更新到第3版但团队里一半人还在按老规范建表新表和旧表风格完全不同。原因文件名叫“3数据库设计规范.doc”靠文件名区分版本但文件在群里传来传去没人知道哪份是最新的。解决文档首页加一张版本变更记录表包含版本号、变更日期、变更人、变更内容摘要文件名固定为“数据库设计规范.doc”不带版本号。doc发布到统一的文档中心或git仓库评审时先核对版本号版本不对直接打回。6. 把规范文档当代码维护doc版本、半自动抽取和一条验收SQL6.1 doc版本管理文件名里的“3”不是序号是血泪把版本号写进文件名的做法我经历过太多坑。第2版和第3版同时在群里流传两个文档内容还不一样最后统一规则文件名不再带版本号版本信息只存在于文档首页的变更记录表和git提交历史里。doc文件放git仓库每次变更走MR评审和代码同一条流水线。别嫌土这是让规范文档活下来的最有效做法。6.2 从doc里抽取建表语句的半自动做法规范文档里的DDL模板通常以代码块形式存在人工复制容易漏。常见做法是用脚本解析docx文档把CREATE TABLE开头的段落自动导出成SQL文件from docx import Document doc Document(数据库设计规范.docx) sql_lines [] capture False for para in doc.paragraphs: text para.text.strip() if text.startswith(CREATE TABLE): capture True if capture: sql_lines.append(text) if capture and text.endswith(;): capture False sql_lines.append(\n) with open(schema_templates.sql, w, encodingutf-8) as f: f.write(\n.join(sql_lines)) print(fextracted {len(sql_lines)} lines)这段脚本的逻辑是扫描段落遇到CREATE TABLE开始收集遇到分号结束一段。参数说明老版本.doc格式需要用WPS或Word另存为.docx再跑脚本如果规范里有多个建表语句脚本会全部导出人工核对一下表名是否有重复。这样规范文档更新后模板SQL能自动同步到仓库避免人手抄错。6.3 一条SQL验收全库合规率最后给一个我每次交接库都要跑的验收SQL统计全库表的注释覆盖率和引擎合规率SELECT COUNT(*) AS total_tables, SUM(CASE WHEN TABLE_COMMENT THEN 1 ELSE 0 END) AS no_comment_tables, SUM(CASE WHEN ENGINE InnoDB THEN 1 ELSE 0 END) AS innodb_tables, SUM(CASE WHEN TABLE_COLLATION LIKE utf8mb4% THEN 1 ELSE 0 END) AS utf8mb4_tables FROM information_schema.TABLES WHERE TABLE_SCHEMA your_db;跑出来如果no_comment_tables占比超过10%说明规范执行已经漏水了不是一朝一夕能补完的但至少知道漏洞面有多大。把这条SQL存成check_schema.sql每次上线前跑一遍合不合规用数据说话比开会吵效率高得多。数据库设计规范这东西最容易烂在“写的时候很认真用的时候没人管”。我自己的习惯是每季度抽半天把全库表结构扫一遍结果贴到文档里有问题的表排期修。规范的价值不在文档本身而在它能不能被反复执行和迭代。希望帮到你。本文还有配套的精品资源点击获取