简介《8数据库设计规范》是一份面向Oracle数据库设计与开发者的规范文档旨在解决系统设计过程中标准不统一、数据模型混乱、字段定义随意等问题适合DBA、后端开发、系统架构师及项目管理者作为内部设计标准参考。文档从数据库策略入手明确对象长度设定、数据完整性实现、规范化设计与性能之间的权衡、字段类型选用等原则并系统给出数据库、表空间、表、字段、视图、序列、存储过程、函数、索引及约束的完整命名规则附表常用字段类型与长度推荐值附录含xml文件使用说明和保留关键字列表。压缩包内仅含1个doc格式文档大小约296KB纯文本资料便于查阅、归档与团队评审。目前已有267人学习下载适用于需要搭建或完善数据库规范的团队和个人。遵循文中约定可有效减少数据冗余、保证数据一致性提升系统可维护性与扩展性也可直接培训新员工或作为评审依据。1. 先别急着建表一份数据库设计规范到底在管什么接手过几个老项目后你会形成一种条件反射打开数据库先数有多少张表再随机挑三张看字段。一个没规范过的库字段名五花八门主键有自增有 UUID 还有业务编号时间字段有的叫 create_time有的叫 created_at有的干脆叫 time。这时候老板甩来一份《8数据库设计规范.doc》告诉你要按这个来你第一反应多半是“这文档能落地吗”。数据库设计规范解决的不是“表怎么建”这种小学数学题而是把命名、类型、约束、索引、SQL 写法这些最容易被拍脑袋决定的事情提前变成可检查、可评审、可追溯的约定。它的服务对象是后端开发、DBA、架构师以及要面对等保和审计的团队。反直觉的是规范最大的收益不在约束而在让每一次数据库结构变更都有据可查也让你在复盘“当初为什么这么设计”的时候不用靠考古。2. 从规范到落地把命名、类型、约束先固化成检查清单2.1 命名规范为什么先统一表名和字段名命名是数据库设计规范里最容易推的部分因为不需要懂业务也能检查。常见做法是先给定一张“命名参照表”把所有高频对象统一收口。表名用{业务域}_{子域}_{动作}比如order_pay_record、user_login_log字段名统一小写加下划线禁止驼峰主键固定叫id逻辑外键统一以{业务对象}_id结尾。这样做的直接好处是开发换项目时不需要重新猜字段含义DBA 写巡检脚本时也有稳定的匹配规则。下面是建议写进规范文档里的命名约定表对象推荐写法反例说明表名order_pay_recordOrderPayRecord、t_order_pay_record全小写、下划线分隔、不用 t 前缀、不用复数主键iduid、order_id每张表必须有主键名字统一为 id逻辑外键order_id、user_idoid、uid直接关联目标表名不缩写时间字段created_at、updated_at、deleted_atcreate_time、update_time、time三张审计字段全表统一方便同步和归档普通索引idx_{表名缩写}_{字段名}index_1、idx_col索引名能看出服务哪张表的哪个字段唯一索引uk_{表名缩写}_{字段名}uniq唯一索引命名和普通索引区分开选型理由很现实MySQL 在 Linux 下默认区分大小写的表名如果开发本地是 Windows 环境OrderPayRecord和orderpayrecord可能被当成两张表代码里一旦大小写写错线上直接报表不存在。字段命名统一之后数据同步工具解析元数据时也不用为每个来源单独做字段映射。落地时不要只写一句“命名要有业务意义”。我一般会把上面的表原样贴到建表评审单里并加一条硬性校验表名长度不超过 32 个字符字段名不超过 30 个字符。超过长度的字段基本说明业务概念拆得不够细需要重新设计。2.2 数据类型与默认值选错类型后面全在还债命名规范是表面功夫数据类型才是决定数据库设计规范有没有价值的关键。见过很多系统订单金额用float存用户状态用char(10)存主键用int存等到数据量上来后才发现要么精度对不上要么主键不够用。规范里最该做的就是把常用业务类型固定下来不允许开发按心情选。下面是一张可以直接作为规范附件的类型选型表业务含义推荐类型不推荐原因主键、计数BIGINT UNSIGNEDINT、VARCHAR单表数据量增长比预期快int 到 21 亿看起来大但分库分表后编号很容易撞上限金额、价格DECIMAL(18,2)FLOAT、DOUBLE浮点数是近似值对账时差一分钱会让人怀疑人生汇率、单价比例DECIMAL(18,4)FLOAT保留精度必须由设计者显式决定不能依赖数据库舍入布尔状态TINYINT(1)CHAR(1)、VARCHAR(1)避免Y和N在不同团队眼里含义不同时间DATETIME(3)TIMESTAMP、VARCHARTIMESTAMP2038 年问题字符串时间无法做区间索引和排序描述类短文本VARCHAR(255)TEXT短文本用TEXT会让排序、默认值、索引都变麻烦JSON 扩展字段JSONVARCHAR(4096)存 JSON 串MySQL 8 的 JSON 类型有校验但禁止在 JSON 字段上建索引做查询条件类型选完还要约定默认值。我的建议是核心业务字段一律NOT NULL DEFAULT给一个业务上无害的默认值可空字段明确允许NULL但要在字段注释里写清楚空值含义。注意一点MySQL 里BLOB、TEXT、JSON类型不能有默认值所以这类字段设计时就要考虑插入路径是否总会显式赋值否则很容易出现 NULL 脏数据。提示这不是“非空强迫症”。规范真正要管的是空值语义。NULL和空字符串、0、1970-01-01在业务上完全不是一回事必须在设计时写明白。2.3 索引设计的最简原则不建多余的索引也不放过明显缺索引索引设计几乎决定了数据库优化能走多远。规范里如果只写“查询慢就加索引”等于没写。更常见的错误是开发为了让一条查询跑得快一口气建了 5 个单列索引结果插入变慢磁盘占用变大查询优化器还不一定用。设计规范应该给出硬性边界单表索引数不超过 5 个联合索引尽量覆盖高频查询禁止为低基数列单独建索引。索引评审时重点看四条规则规则说明必须有主键索引没有主键的表在复制、同步、备份恢复时都可能出问题联合索引遵循最左前缀字段顺序按“等值条件在前、排序或范围条件在后”排列禁止对索引列做函数运算WHERE DATE(created_at) 2024-01-01会让索引失效应改成范围查询唯一约束用唯一索引实现业务唯一性不能靠应用层判断必须有数据库兜底索引设计不是 DBA 一个人的事。开发在提交建表申请时必须回答“这个表会被哪些查询用到、查询条件是什么、期望返回多少行”。如果一张表设计时完全没考虑查询路径后面所有优化都是在打补丁。规范里可以加一条单表超过 500 万行时必须提前说明数据生命周期并配套归档或分区方案不能等到慢查询报警再看。2.4 把规范变成一张“建表评审单”文档写得再漂亮不落到评审单里就是废纸。这是我从多个项目里得到的教训。规范类文档最大的问题是“说得都对做的时候忘了”。解决办法很简单把规范浓缩成一张不超过 20 行的建表评审单每次结构变更都先过评审单再合代码。推荐使用一票否决制评审单评审项通过标准一票否决项表名与字段命名符合 2.1 约定无保留字出现驼峰、复数、中文拼音命名主键显式BIGINT主键无主键、用业务编号做主键字符集库、表、字段统一utf8mb4同一张表内字段字符集不一致数据类型金额DECIMAL时间DATETIME布尔TINYINT用FLOAT存金额默认值核心字段NOT NULL DEFAULT空值语义明确该有默认值却没有且运行时代码不保证赋值的字段索引高频查询有索引单表索引 ≤ 5完全重复索引、索引列含函数物理外键禁止物理外键使用逻辑外键在核心业务表上使用FOREIGN KEY级联删除这张评审单可以直接附在《8数据库设计规范.doc》后面。使用原则是不是 “提示建议”而是 “不合规就打回”。就算最终需要特批也必须由架构师在评审单上签字留下记录避免下次又有人拿“上次也这么干”当挡箭牌。3. 把规范接进开发流程从建表审批到慢查询闭环3.1 建表审批要卡住哪几个环节规范文档只是静态约定真正让它生效的是变更流程。常见做法是把数据库结构变更分成四类新建表、加字段、改字段类型、加索引。每一类在 DDL 执行前都要过审批不是只有新建表才需要评审。改字段类型最容易被低估比如把VARCHAR(50)改成VARCHAR(200)在 MySQL 8 里可能可以做在线变更但如果原表有 1000 万行执行时一样要小心锁和临时表。我建议的审批环节是开发提交结构变更申请必须附带业务背景、预计数据量、查询场景说明。DBA 或技术负责人按评审单逐项打勾重点关注索引和空值语义。变更脚本先在测试环境执行用SHOW CREATE TABLE对比实际结构是否符合预期。新表首次上线后观察 3 天查看慢查询日志中是否有针对新表的全表扫描。变更申请表归档到工单系统作为后续审计和排障的参考依据。很多团队只做到第 2 步就放行导致测试环境能用、生产环境一上线就慢。原因很典型测试环境数据量小全表扫描也能秒回生产环境才暴露出缺索引。规范文档里应当明确只要涉及新查询就必须在评审单里附上EXPLAIN结果。如果开发说“数据量不大不用建索引”那就让他在评审单里写清楚“预估最大数据量不超过 10 万行”并签字。3.2 用元数据视图给全库做“规范体检”结构变更评审能管住新表管不住存量表。现实情况是很多数据库里一半以上的表是历史遗留没人愿意动但又不能一直放任。解决办法是做周期性的“规范体检”用数据库自带的元数据视图扫一遍全库。体检项可以固定为以下五类体检项元数据来源通过标准无主键表information_schema.tables和statistics全库不存在无主键表字符集不统一information_schema.schemata、tables、columns库、表、字段三级字符集一致重复索引statistics按索引名和列分组不存在完全相同的索引组合命名违规字段columns检查驼峰、保留字、反引号命名符合 2.1 约定可疑类型字段columns检查float、int主键金额不是float主键不是int体检本身不复杂复杂的是把结果变成改进项。我一般会每周一上午跑一遍体检把结果发到技术群里连续三周出现同一类问题的表再走整改。这样既不会让开发觉得 DBA 在找茬也能让问题在变严重之前被看见。规范体检查出来的问题不要急着直接改线上表。比如把INT主键改成BIGINT在 MySQL 里要重建表可能造成长时间锁等待必须先评估在线变更工具和停机窗口。这也是设计规范里要写“存量表整改另走变更流程”的原因。3.3 从建表规范延伸到 SQL 规范连接池、批量写和锁等待数据库设计规范如果只管表结构不管 SQL 怎么写很容易出现“表设计没问题但业务跑不起来”的情况。一套可落地的规范必须连访问数据库的方式一起约束。常见做法是把 SQL 规范按场景拆成几条硬规则和表结构评审一起过。连接池是最容易被忽略的环节。很多项目把max_connections设成 200四个应用实例每个连接池也配 200结果数据库真实连接数直接破千。规范里应该明确连接池上限要按“实例数 × 最大连接数 数据库最大连接数 × 0.7”来压测校准而不是拍脑袋配。连接池满后的表现是应用偶发超时数据库端看连接数已经打满这时候再加内存、加 CPU 都没用。批量写和事务也要在规范里写死。比如场景规范要求批量插入单批 500 到 1000 行使用 prepared statement 批量提交单事务时长控制在 1 秒内禁止事务内调用第三方接口或 sleep更新顺序多表更新时按固定顺序加锁避免并发锁死锁锁等待InnoDB 事务锁等待超时设置为 5 秒超时立即回滚慢查询超过 200 毫秒的 SQL 必须有索引支撑否则走评审为什么事务要控制在 1 秒内因为事务越长持有锁的时间越长数据库并发锁冲突概率越高死锁回滚带来的业务失败就越频繁。用连接池的团队往往忽视这一点事务里发起 HTTP 调用连接一直被占用其他请求只能排队。数据库设计规范里把这些写清楚比单纯要求“少用锁”更有操作性。4. 数据库设计规范要避开的 5 个坑4.1 规范写完就吃灰新表继续乱建现象规范文档挂在 Wiki 上阅读量不少但开发建表时根本不打开。新项目上线后依然出现tb_user_info202401这种表名主键还是varchar(64)。原因规范没有嵌入开发工具和评审流程大家只把它当“参考”不当“强制”。文档是静态的人是懒惰的如果打开 IDE 建表时看不到规范入口规范就等于不存在。解决把规范转成一张建表评审单并在工单系统里做成必填项。提交建表申请时先自检不合规直接不能提交。再配合每周元数据体检把违规表名发到工作群形成压力。文档存在的意义不是被阅读而是被引用。4.2 只规范了表结构没规范 SQL 怎么写现象表结构完全符合规范有主键、有统一时间字段、有合理索引。但业务代码里SELECT *满天飞连表查四张表批量更新一次更新 20 万行数据库很快被打挂。原因设计规范只写了“数据库长什么样”没写“应用程序该怎么访问”。开发想的是快速实现功能不会主动考虑连接池和锁等待。解决SQL 规范不要单独成册直接作为数据库设计规范的附录。评审建表时顺带评审这条表会引发的核心 SQL至少让开发把最常用的三条查询写出来看有没有索引支撑。4.3 把“不用 NULL”当铁律反而引发兼容问题现象规范要求所有字段NOT NULL。结果一个用于存用户备注的字段被写成NOT NULL DEFAULT 业务逻辑里分不清“用户没填”和“用户填了空字符串”还有一个日期字段默认1970-01-01同步到报表系统后被当成真实业务时间。原因把“避免 NULL”错误理解为“所有字段都非空”。这里面缺少空值语义设计默认值并不比 NULL 更安全。解决规范里区分两类字段必须非空字段和允许空值字段。对于允许空值的字段直接在注释里写明“NULL表示未填写空字符串表示填写为空”应用层按语义处理。不要搞一刀切。4.4 只写了 MySQL 方言国产数据库改造时全得重来现象规范里写死了AUTO_INCREMENT、ON UPDATE CURRENT_TIMESTAMP、ENGINEInnoDB、TINYINT(1)。项目要做国产数据库适配时发现一轮改造要改几百张表工作量极大。原因规范文档没有分层把平台特性当成了通用设计。遇到达梦、人大金仓这类数据库语法差异直接暴露。解决规范分两层核心层只写表名、字段、主键、约束、索引等逻辑规则方言层单独记录各数据库的 DDL 差异。MySQL 的ON UPDATE语法在达梦里就不要再依赖改为应用层更新updated_at这是更稳妥的方案。4.5 没有自动巡检和评审闭环靠人肉根本不长久现象刚开始有 DBA 盯着评审前三个月还好后来团队扩张一天提交十几个建表需求评审变成签字走形式违规结构悄悄流入生产。原因评审体系依赖个人责任没有工具支撑。数据库优化和设计规范不应该是救火而应该靠自动化巡检提前发现问题。解决哪怕用最原始的定时脚本也要把违反命名、无主键、字符集不一致、重复索引这些问题扫描出来。把巡检结果和工单系统打通违规表自动生成整改任务。没有这一步规范永远停留在 doc 层面。5. 规范也要“向下兼容”同步、迁移与多数据库环境怎么定边界5.1 核心规范与方言规范分开写一份数据库设计规范如果只能在 MySQL 上成立那它的生命周期就太短了。现在不少企业同时存在 MySQL、PostgreSQL、达梦、人大金仓甚至老的 Oracle。迁移和适配最怕的不是表结构复杂度而是设计时把方言当默认项。建议把规范分成两层规范层内容范围举例核心规范表名、字段名、主键、约束、索引逻辑设计每表必须有主键金额用DECIMAL时间统一DATETIME方言规范不同数据库的 DDL 和函数实现差异自增字段MySQL 用AUTO_INCREMENT达梦用IDENTITY或序列分页MySQL 用LIMITOracle/达梦用FETCH FIRST方言层不要写在主文档里而是作为附录或独立适配文档。这样团队在 MySQL 上开发时不会因为看到一堆达梦语法而困惑等做国产数据库适配时核心层不用动只把方言层替换掉。这里有一个很实用的约束新表设计阶段一律先写核心规范描述再生成方言 DDL。比如主键字段核心定义是“BIGINT非空唯一标识”具体在哪个库用自增还是序列由方言层决定。很多迁移翻车就是因为设计时直接依赖了 MySQL 的AUTO_INCREMENT迁移到人大金仓时才发现序列对象没建好。5.2 数据同步要求要写进设计规范做数据库设计如果没考虑数据同步后面一定得补课。无论是用数据库同步工具做实时分析还是把数据从业务库同步到数仓源表设计直接决定同步链路能不能稳定跑起来。规范里至少要有以下几条同步要求设计规范约定增量同步每张核心表必须有主键且更新时刷新updated_at字段删除同步大表统一逻辑删除禁止物理删除同步端才能拿到删除标记DDL 同步表结构变更必须走审批禁止直接在生产库执行ALTER TABLE绕过同步工具类型映射尽量不使用无法被同步工具解析的自定义类型比如 MySQL 的JSON到达梦时可能变成字符串为什么强调updated_at因为大部分增量同步工具默认按主键或时间戳拉取。如果表里没有统一更新时间字段同步任务只能全量扫描数据量一大就延迟。还有一点同步工具需要稳定的主键。如果主键是业务编号而业务上允许修改编号那同步链路一定出乱子。规范里可以直接禁掉“业务编号做主键”改用无业务含义的id。5.3 向量数据库和日常业务表各归各位热词“向量数据库”这几年很火但数据库设计规范不需要把所有数据都塞进一个库里。规范真正要管的是边界核心交易数据进 OLTP 库分析数据进数仓向量数据进向量库缓存数据进 Redis。如果一张业务表既要被事务查询又要存 embedding 做相似度检索那设计上就出现了职责混淆。规范的约束是向量库只保存实体 ID、向量值和必要的过滤字段不带完整业务字段。业务主数据必须还在原事务库中对外查询以主数据为准。同步到向量库的数据通过 MQ 或同步任务异步推送不直接写在事务里。这样即使向量库出现故障也不会影响核心交易。数据库设计规范的价值就在于提前划清这些边界省得每个新项目都争论“该用哪个库”。6. 让规范活起来的最后一个技巧用反例驱动新人评审6.1 把“不许做”变成一眼能看懂的坏味道很多规范文档读起来像教材新人看完也不知道自己哪里错了。后来我养成了一个习惯在规范最后附一张“反例清单”把从真实代码里见过的坏味道一条条写出来。新人不看枯燥的“应然”但对“原来这是错的”记得特别深。坏味道评审时怎么问表名带日期order_202401这个日期是分区后缀还是固定表名固定表名意味着明年要建新表要不要设计成一张表字段名is_delete、delete_status删除标记和业务状态是否混在一起逻辑删除和物理删除谁负责主键varchar(64)存业务编号这个编号未来可不可能被修改修改主键的成本你确认过吗金额double对账时小数点后出现 0.30000000000000004 你打算怎么解释单表 8 个索引每个索引都能找到对应慢查询吗没有索引支撑的索引就是浪费写性能6.2 我每次评审必问的三个问题第一这张表五年后大概多少行如果超过一千万分表、分区、归档策略在哪第二谁会怎么查这张表把主要 where 条件和 order by 字段写出来我再决定索引方案。第三数据怎么进来、怎么出去、怎么删除这三个问题能回答清楚表结构设计基本不会太差。如果开发回答“不知道”我不会直接打回而是建议他先确认业务容量和查询场景再回来评审。这不是刁难而是避免建出一张谁都不敢动的“黑匣子”表。数据库设计规范不是 DBA 的枷锁它其实是给开发的一张后悔药清单只要你按规范走就算做错了也能顺着评审记录快速找到改的方向。6.3 验证把反例清单挂到建表自检最后一步我现在做的项目里建表工单模板最后一步固定是三行自检表名和字段名能否在反例清单里找到影子主键是否满足五年容量预估最重要的查询有没有对应索引开发自己打完勾评审人才开始看。这个习惯比任何培训都有效至少让新人知道“被人挑毛病之前先自己挑一遍”。数据库设计规范这件事最怕的不是文档写得好不好而是没人把它当工程基础设施来用。我见过太多规范 doc 躺在文件夹里吃灰也见过靠一张反例清单把一个团队的表结构掰回正轨的例子。希望你接手时也能让这份《8数据库设计规范.doc》变成真正能挡住问题的第一道防线希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?