☰
数据库设计文档编写指南:从ER图到SQL Server DDL落地实践
2026/10/3 7:52:45 网站建设 项目流程

简介:这份《数据库设计文档.pdf》面向人资信息管理系统的开发、测试与数据库设计人员,用于统一后台数据库的概念模型与物理模型规范,并明确各表的数据字典结构,是编码与测试阶段的重要参考依据。文档围绕数据库环境说明、命名规则、逻辑设计与数据库实施四部分展开:环境部分采用SQL Server数据库管理系统,配合Visio绘制ER图并生成DDL脚本;命名规则遵循三范式,库名与表名统一大写,表以RSH_前缀加中文拼音缩写命名,如职工基本信息表RSH_ZHGJB。逻辑设计按面向对象思想由实体类生成数据表,实施部分基于SQL Server 2008 R2,库名DB_OA,包含SendMessage、ReadMessage、Role、RolePrivilege、Privilege、User、RecordBackUp、Plan、Company等表,并逐表说明功能与字段类型、长度及约束。资源包为1个PDF文件,大小约296KB,结构紧凑便于查阅。目前已有673人学习下载,适合需要参考建库规范、表结构设计与数据字典编写思路的读者。

1. 数据库设计文档.pdf:一份能落地的设计文档到底该写什么

很多人第一次拿到「数据库设计文档.pdf」这个任务时,脑子里蹦出来的是一张 ER 图加几张建表语句,觉得凑齐就能交差。真到开发拿着文档建库、联调、上线,问题全冒出来了:字段类型对不上、索引漏建、外键约束在 SQL Server 里和 MySQL 行为不一致、密码字段存了明文、MD5 校验值长度写成了 32 位却按 varchar(64) 建表。一份合格的数据库设计文档,本质是给「未来的自己和接手的人」留的后悔药,它要能让一个没参与过需求评审的工程师,照着文档把库建出来、把数据灌进去、把接口对上去。

这篇笔记围绕「数据库设计文档.pdf」这个标题,把一份可交付的设计文档拆成能复现的步骤:从 ER 图怎么画、DDL 怎么写、字段和索引怎么定,到 SQL Server 环境下的具体建库命令、MD5 这类摘要字段的处理边界,再到交付前怎么自检。适合正在写课程设计、毕业设计、公司内部技术文档,或者接手了一个只有口头需求、需要补文档的工程师。读完你应该能独立产出一份别人敢照着建库的文档,而不是一张好看的图。

2. 从需求到 ER 图:实体、关系和那几条不能省的约束

2.1 先定实体边界,再谈画图工具

ER 图翻车的根源几乎都不在画图工具,而在实体边界没定清楚。常见做法是先把需求里的名词圈出来,逐个判断它是实体、属性还是值对象。比如「博客系统」里,用户、文章、评论、标签是实体;「文章标题」是属性;「文章状态(草稿/发布)」如果只有固定几个值,就是属性加枚举约束,不值得单独建表。判断标准很简单:这个东西有没有独立的生命周期、需不需要被别的表引用、会不会单独查询。三个里中两个,就建表。

工具层面,Rational Rose 是老一辈课程设计里的常客,现在更多人用 MySQL Workbench 反向导出 ER 图,或者直接用 mermaid 写文本化的 ER 图,方便进 Git 做版本管理。工具不影响文档质量,影响的是协作效率。我一般会先用 mermaid 把关系草稿写出来,确认无误后再用图形工具出终稿贴进 PDF。

erDiagram USER ||--o{ ARTICLE : writes ARTICLE ||--o{ COMMENT : has USER ||--o{ COMMENT : posts ARTICLE }o--o{ TAG : tagged

上面这段是关系草稿,注意几个点:||--o{表示一对多且子表可为空,}o--o{表示多对多。多对多关系在物理建模时必须拆成中间表,比如article_tag(article_id, tag_id),主键用两列联合,不要图省事在文章表里塞一个逗号分隔的 tag 字段,那是后面所有查询性能问题的源头。

2.2 关系基数与可选性:别让「一对多」变成「多对多」

关系基数写错是设计文档里最隐蔽的坑。举个真实场景:一个用户可以有多个收货地址,一个地址属于一个用户,这是一对多。但如果业务允许「一个地址被多个用户共享」(比如公司统一收货点),那就变成多对多,需要中间表。文档里必须把可选性写清楚:是「每个用户至少有一个地址」还是「可以有零个」。这直接决定外键列能不能为 NULL,以及删除用户时地址怎么处理。

在 SQL Server 里,外键的可选性通过列是否允许 NULL 和ON DELETE行为共同表达。常见做法是:从属关系用ON DELETE CASCADE,引用关系用ON DELETE NO ACTION并在应用层做校验。文档里要明确写出每个外键的删除策略,否则开发默认全用 NO ACTION,上线后删主表数据报错,回头再改就是一次线上变更。

2.3 把 ER 图翻译成表结构清单

ER 图是给人看的,表结构清单是给机器和开发看的。文档里这两部分必须一一对应。我一般用一张表把每个实体落成物理表,列出表名、中文名、说明、预估数据量级。量级很重要,它决定后面索引策略和分区要不要考虑。下面是一个用户信息表的清单示例:

表名中文名说明预估量级
user_info用户信息表存储注册用户基础信息百万级
article文章表博客文章主体千万级
comment评论表文章评论,支持二级回复亿级

量级到亿级的表,主键类型、索引数量、是否分表都要提前在文档里给结论,不能等开发自己拍脑袋。评论表这种量级,主键用 bigint 自增,不要用 GUID,GUID 做主键在 SQL Server 里会导致页分裂和索引膨胀,这是血泪经验。

3. 写 DDL:字段类型、约束和 SQL Server 的落地命令

3.1 字段类型选择:从 MD5 字段长度说起

字段类型选错,后面改起来代价极大。拿热词里的 MD5 举例:MD5 摘要固定 128 位,十六进制表示是 32 个字符。所以存 MD5 值的列,用char(32)而不是varchar(64),定长比变长在索引和存储上都更优。如果存的是二进制形式,用binary(16)。文档里要写清楚存的是哪种形式,否则前端传 32 位十六进制、后端按 binary 解析,直接对不上。

常见字段类型对照:

业务含义推荐类型说明
自增主键bigint避免 int 溢出,亿级表必须
短文本(姓名、标题)nvarchar(50~200)SQL Server 下中文用 nvarchar
金额decimal(18,2)绝不用 float
时间datetime2比 datetime 精度高,范围大
布尔bitSQL Server 没有 boolean
MD5 摘要char(32)定长十六进制

金额用 float 是经典翻车点,0.1+0.2 不等于 0.3,对账时能查到你怀疑人生。时间字段用 datetime2 而不是 datetime,后者精度只有 3.33 毫秒,高并发下同一秒的多条记录排序会乱。

3.2 建表 DDL 的完整写法与注释

下面是一段可直接在 SQL Server 里执行的建表语句,包含主键、外键、默认值、索引和注释。注释在 SQL Server 里用扩展属性实现,很多人会漏,导致文档和库对不上。

-- 用户信息表 CREATE TABLE user_info ( user_id BIGINT IDENTITY(1,1) NOT NULL, user_name NVARCHAR(50) NOT NULL, password_md5 CHAR(32) NOT NULL, -- 存 MD5 十六进制摘要 email NVARCHAR(100) NULL, status TINYINT NOT NULL DEFAULT 1, -- 1正常 0禁用 create_time DATETIME2 NOT NULL DEFAULT SYSDATETIME(), CONSTRAINT pk_user_info PRIMARY KEY (user_id), CONSTRAINT uq_user_name UNIQUE (user_name) ); -- 给状态列建索引,后台按状态筛选用户 CREATE INDEX ix_user_info_status ON user_info(status); -- 添加列注释(扩展属性) EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'用户唯一标识', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'user_info', @level2type = N'COLUMN', @level2name = N'user_id';

逻辑说明:IDENTITY(1,1)是 SQL Server 的自增写法,起始 1 步长 1。password_md5用 char(32) 定长,因为 MD5 十六进制长度固定。status用 tinyint 而不是 int,省空间。create_time默认值用SYSDATETIME()而不是GETDATE(),前者精度更高。索引单独建,不要在主键里堆。

参数说明:uq_user_name是唯一约束,保证用户名不重复,它本身会创建一个唯一索引。如果业务允许重名但要求登录名唯一,那唯一约束应该建在登录名字段上,而不是昵称字段。这个区分文档里必须写明白,否则开发容易建错。

3.3 索引策略:哪些列该建,哪些是负担

索引不是越多越好。写多读少的表,索引多了拖慢插入。判断标准:出现在 WHERE、JOIN ON、ORDER BY 里的列优先考虑;区分度低的列(比如性别只有两三个值)不单独建索引;组合索引注意最左前缀原则。文档里我一般会列一张索引清单,写清楚每个索引服务的查询场景。

索引名表列服务场景
ix_article_userarticleuser_id, create_time查某用户文章按时间倒序
ix_comment_articlecommentarticle_id, create_time查文章评论分页
ix_user_info_statususer_infostatus后台按状态筛选

组合索引的列顺序按「等值条件在前、范围条件在后」排。ix_article_user里 user_id 是等值,create_time 是范围排序,顺序不能反。反了的话,按时间范围查就用不上这个索引。

4. 避坑与排查:数据库设计文档交付前的五道关

4.1 现象:开发建库报「外键引用列不存在」

原因通常是 ER 图里关系画了,但 DDL 里被引用的表还没建,或者建表顺序错了。SQL Server 建外键时要求被引用表和列已存在。解决:DDL 按依赖顺序排列,先建无外键的主表,再建从表;或者先建所有表,最后统一ALTER TABLE ADD CONSTRAINT加外键。文档里我一般把外键单独成段,标注执行顺序。

4.2 现象:MD5 字段存进去长度对不上,查询查不到

原因有两种:一是列定义成 varchar(32) 但实际存了带盐的 64 位值,被截断;二是前端传的是大写十六进制,库里存的是小写,比较时大小写敏感导致查不到。解决:文档里明确 MD5 是否加盐、盐值怎么拼、存大写还是小写。SQL Server 默认排序规则不区分大小写,但如果列用了二进制排序规则就会区分,这点要在文档里写死。

4.3 现象:SQL Server 连接报 SSL 证书链不受信任

这是热词里高频出现的报错,[08001] ... 证书链是由不受信任的颁发机构颁发的。原因通常是客户端驱动(ODBC Driver 17/18)默认开启了加密,而服务器用的是自签名证书。解决:在连接字符串里加TrustServerCertificate=True,或者把自签名证书导入客户端信任库。文档里如果涉及连接配置,要把这个参数写进去,否则每个新环境都要踩一遍。

4.4 现象:datetime 字段排序出现同秒乱序

原因是用 datetime 精度不够,同一秒内多条记录时间值相同,排序不稳定。解决:改用 datetime2,精度到 100 纳秒。如果已经建表,ALTER TABLE ... ALTER COLUMN改类型,注意改之前备份。文档里时间字段统一用 datetime2,从源头避免。

4.5 现象:文档里的表和实际库不一致

原因是有人直接在库上改了字段没回写文档。解决:把 DDL 脚本纳入版本管理,文档里的表结构从脚本生成,而不是手写。每次变更先改脚本,再执行,再导出文档。这样文档和库永远一致。我一般会在文档开头写一句「本文件由 schema.sql 生成,请勿手工修改表结构部分」。

5. 交付前的自检清单与一个提效技巧

文档写完别急着交,过一遍自检清单能省掉后面大量返工。下面这张表是我每次交付前必查的项:

检查项通过标准
每个实体有对应物理表ER 图与表清单一一对应
每个字段有类型和说明无「待定」「TBD」
主键、外键、唯一约束齐全外键标注删除策略
索引清单与查询场景匹配每个索引有服务场景
敏感字段处理明确密码类字段注明摘要算法
DDL 可独立执行在空库上跑一遍无报错

最后分享一个提效技巧:把 DDL 脚本和文档生成绑在一起。用 SQL Server 的sp_addextendedproperty把中文说明写进库,再用脚本把表结构和扩展属性导出成 Markdown 表格,直接贴进文档。这样字段说明永远和库同步,不用手工维护两份。我现在的习惯是,任何表结构变更,先写ALTER脚本,执行后立刻重新导出文档片段,提交时脚本和文档一起进版本库。吃过一次「文档写 A、库里是 B」的亏之后,这个习惯就再也没改过。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询