news 2026/10/13 8:10:50

database-doc-generator:基于DDL的数据库文档自动化生成工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
database-doc-generator:基于DDL的数据库文档自动化生成工具

简介:这是一款轻量级Java开发的数据库文档自动生成工具,面向后端开发者、DBA及技术文档工程师,解决PowerDesigner等重型建模工具部署复杂、学习成本高的痛点,适用于日常数据库表结构沉淀、团队知识共享与项目交付文档快速输出。资源包共21个文件,含10个核心Java源码(实现多数据库驱动适配与模板渲染)、3张功能示意图(jpg)、2个配置文件(xml)、1个Windows启动脚本(bat)与1个Linux启动脚本(sh),辅以README.md、pom.xml及HTML格式说明文档,整体仅188KB,开箱即用且便于二次定制。已有326人学习下载,用户可直接运行编译后的程序,按交互式提示选择PostgreSQL/MySQL/Oracle类型,输入库名、主机、端口及账号密码,即可一键生成结构清晰的Markdown与Word格式文档,涵盖表名、字段、类型、注释及关系说明,显著提升数据库文档维护效率。

1. 这不是又一个“导出说明书”的玩具:database-doc-generator 是能嵌进 CI 流水线的轻量级数据库文档自动化引擎

你有没有在交付前最后一刻,被产品追着要「最新版数据库字段说明」?有没有因为某张表加了个is_deleted字段没同步到 Confluence,导致测试环境查不到软删数据而翻车?更糟的是,用 PowerDesigner 或 ER/Studio 这类重型建模工具——画个图要装 2G 客户端、配 JDK 版本、改注册表、导出 Word 还得手动删页眉页脚……结果文档刚生成,开发已经ALTER TABLE加了三列。database-doc-generator 就是为这种真实血泪场景生的:它不碰 ER 图、不依赖 GUI、不维护元模型,只认一件事——你数据库里SHOW CREATE TABLE出来的那一段 DDL 字符串。用 Java 写成的命令行工具,5 分钟配置完,java -jar docgen.jar --url jdbc:mysql://...一跑,立刻吐出结构清晰、带注释解析、支持 Markdown 和 Word 双格式的文档。适合中小型团队做数据库契约管理、新人快速上手、CI 中自动校验 DDL 变更是否同步到文档库。它不替代 DBA 的深度建模,但能让你告别「文档永远比代码慢半拍」的玄学困境。


2. 为什么选它?不是因为“轻”,而是因为它把 DDL 当唯一真相源

2.1 DDL 即契约:拒绝元数据二义性,从根源掐断文档漂移

很多团队用注释(如@Table(name = "user", comment = "用户主表"))或实体类 Javadoc 生成文档,问题在于:Java 类可以改,DDL 可能没同步;DBA 直接 SQL 建表,Java 类却忘了更新;甚至不同环境 DDL 已分叉,文档还指着旧类。database-doc-generator 的设计哲学非常硬核:它完全不读 Java 实体类、不连 Hibernate SessionFactory、不解析 MyBatis XML 映射文件。它只做三件事:

  1. 通过 JDBC 连接数据库(或读取本地 SQL 文件);
  2. 执行SHOW CREATE TABLE xxx或解析CREATE TABLE语句;
  3. 把COMMENT、DEFAULT、NOT NULL、KEY、ENGINE等原生 DDL 属性,逐字映射为文档字段。

这意味着:只要你的生产库information_schema是可信的,生成的文档就一定是当前真实状态。我曾在某模拟项目X 的灰度发布中,用它每小时扫描一次核心库,发现两个环境间user_profile表的updated_at字段默认值不一致(一个是CURRENT_TIMESTAMP,一个是NULL),这个差异在人工 review DDL 脚本时被漏掉了——而 docgen 的 Markdown 输出里,两行Default值并排写着,一眼揪出。

2.2 Java 实现的底层优势:可控、可嵌入、可审计

它用 Java 写,不是为了“跨平台”这种空话,而是三个实打实的好处:

  • JDBC 驱动全生态兼容:MySQL 5.7/8.0、PostgreSQL 12+、Oracle 19c、SQL Server 2019,只要 JDBC URL 能通,它就能连。不像某些 Python 工具对 Oracle cx_Oracle 版本极其敏感;
  • 无运行时依赖污染:打包成单 jar,不依赖系统 Python 环境、不装 node-gyp 编译、不拉 npm 包。运维同学扔进 Docker 容器里,java -version检查完就能跑;
  • 日志与异常完全可控:所有 SQL 执行、字段解析、模板渲染过程,都走 SLF4J,DEBUG 级别下能看到每一行 DDL 是怎么被切分成列名、类型、注释的。某次遇到 MySQL 8.0 的json类型解析失败,打开 DEBUG 日志,30 秒定位到TypeParser类里少处理了一个JSON枚举值——补上后重新编译,问题消失。这种可调试性,在 shell 脚本或 JS 工具里是奢侈品。

2.3 Markdown + Word 双输出:不是噱头,是交付链路的真实需求

很多人觉得 “Word 输出” 是过时功能,但现实很骨感:

  • 向客户交付系统时,合同要求提供.docx格式《数据库设计说明书》,盖章归档;
  • 内部审计需要 Word 文档插入页眉(含密级标识)、页脚(含版本号和生成时间);
  • 非技术人员(如业务方)更习惯双击打开 Word 查字段,而不是在 VS Code 里看 Markdown。

database-doc-generator 的 Word 输出不是简单 HTML 转 DOCX,而是用 Apache POI 直接操作 OOXML 结构:表格用XWPFTable生成,标题用XWPFParagraph设置样式,甚至支持自定义 Word 模板(.docx文件里预设好公司 Logo 位置、字体、页边距)。而 Markdown 输出则严格遵循 GitHub Flavored Markdown,表格对齐、代码块语法高亮、链接跳转全部可用,直接丢进 GitBook 或 Docsify 就能当在线文档站用。两者共享同一套解析引擎,保证内容零偏差——这是很多“先转 Markdown 再用 pandoc 转 Word”的方案做不到的。


3. 三步落地:从下载到生成一份可交付的数据库文档

3.1 下载与环境准备:确认 JDK 版本,拒绝“版本玄学”

提示:该工具最低要求 JDK 8u202+,推荐使用 JDK 11 LTS。JDK 17+ 也可用,但需确认 JDBC 驱动兼容性(如 MySQL 8.0 驱动需 8.0.33+)。

第一步,去 GitHub Release 页面下载最新版 jar 包(截至本文撰写时最新为v2.3.1,文件名形如database-doc-generator-2.3.1.jar)。不要用git clone后自己mvn package——除非你明确要改源码,否则官方 release 包已包含所有依赖(Shaded Jar),开箱即用。

第二步,确认 Java 环境:

java -version # 正确输出应类似: # openjdk version "11.0.22" 2024-01-16 # OpenJDK Runtime Environment (build 11.0.22+7-post-Ubuntu-0ubuntu2~22.04.1) # OpenJDK 64-Bit Server VM (build 11.0.22+7-post-Ubuntu-0ubuntu2~22.04.1, mixed mode, sharing)

若提示command not found,请先安装 OpenJDK 11(Ubuntu/Debian):

sudo apt update && sudo apt install openjdk-11-jdk -y

第三步,准备数据库连接凭证。强烈建议不要在命令行明文写密码,改用配置文件方式(更安全、可纳入 Git 忽略):

# 创建 config.yaml(路径随意,比如 ./conf/db-config.yaml) cat > ./conf/db-config.yaml << 'EOF' jdbc: url: "jdbc:mysql://192.168.5.100:3306/myapp_db?useSSL=false&serverTimezone=Asia/Shanghai" username: "doc_reader" password: "your_secure_password" driver-class-name: "com.mysql.cj.jdbc.Driver" output: format: ["markdown", "word"] markdown: output-dir: "./docs/markdown" word: template-path: "./templates/company-template.docx" # 若无此文件,用默认模板 output-dir: "./docs/word" tables: include: ["user", "order", "product"] # 只生成指定表,留空则全库 exclude: ["audit_log_%"] # 支持通配符排除 EOF

注意:doc_reader账号只需SELECT权限(查information_schema.TABLES/COLUMNS),绝不给SUPER或FILE权限,符合最小权限原则。

3.2 命令行执行:支持三种输入模式,按需选择

工具支持三种数据源模式,对应不同协作阶段:

▶ 模式一:直连数据库(开发/测试环境常用)
java -jar database-doc-generator-2.3.1.jar \ --config ./conf/db-config.yaml \ --verbose

--verbose参数会打印详细日志:连接成功、查询了哪些系统表、解析了多少张表、生成了几个文件。首次运行建议必加,便于排查连接问题。

▶ 模式二:解析本地 SQL 文件(CI/CD 流水线首选)

当数据库无法直连(如生产库隔离),或需确保文档与发布包 DDL 严格一致时,让 DBA 提供schema-ddl-20240501.sql文件:

java -jar database-doc-generator-2.3.1.jar \ --sql-file ./ddl/schema-ddl-20240501.sql \ --output-format markdown,word \ --output-dir ./docs/generated/

此时工具会跳过 JDBC 连接,直接用正则 + ANTLR 解析 SQL 文件中的CREATE TABLE语句。它能正确处理多语句、反引号包裹的表名、跨行定义——这点比手写 sed/awk 脚本可靠得多。

▶ 模式三:指定单表 DDL 字符串(紧急救火用)

当某张表结构突变,需立刻生成说明发给前端,又来不及改配置时:

echo "CREATE TABLE user (id BIGINT PRIMARY KEY COMMENT '用户ID', name VARCHAR(50) NOT NULL COMMENT '用户名') ENGINE=InnoDB;" | \ java -jar database-doc-generator-2.3.1.jar \ --stdin-dll \ --output-format markdown \ --output-dir ./tmp/

--stdin-dll参数告诉工具从标准输入读 DDL,适合管道操作。生成的user.md会包含字段表、索引说明、建表语句原文,5 秒搞定。

3.3 输出结构详解:不只是字段列表,而是可执行的数据库契约

生成的 Markdown 文档目录结构如下(以./docs/markdown/为例):

├── README.md # 总览:数据库名、生成时间、表总数、统计摘要 ├── tables/ │ ├── user.md # 每张表独立文件 │ ├── order.md │ └── product.md ├── indexes/ # 独立索引说明(含联合索引字段顺序) │ └── idx_user_status_created.md └── constraints/ # 外键、检查约束详情 └── fk_order_user_id.md

打开tables/user.md,你会看到:

# `user` 表说明 > **数据库**: myapp_db &nbsp; **引擎**: InnoDB &nbsp; **字符集**: utf8mb4 &nbsp; **生成时间**: 2024-05-20 14:22:36 | 字段名 | 类型 | 允许为空 | 默认值 | 键 | 注释 | |--------|------|----------|--------|----|------| | `id` | `BIGINT` | ❌ | `NULL` | `PRI` | 用户ID | | `name` | `VARCHAR(50)` | ❌ | `NULL` | | 用户名 | | `status` | `TINYINT` | ✅ | `0` | | 状态:0-禁用,1-启用 | | `created_at` | `DATETIME` | ✅ | `CURRENT_TIMESTAMP` | | 创建时间 | **索引**: - `PRIMARY KEY (id)` - `KEY idx_user_status (status)` **建表语句**: ```sql CREATE TABLE `user` ( `id` bigint NOT NULL COMMENT '用户ID', `name` varchar(50) NOT NULL COMMENT '用户名', `status` tinyint DEFAULT '0' COMMENT '状态:0-禁用,1-启用', `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), KEY `idx_user_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户主表';
注意:`允许为空` 列用 ❌/✅ 直观表示 `NOT NULL`/`NULL`;`键` 列用 `PRI`/`MUL`/`UNI` 标准缩写;所有注释(`COMMENT`)原样保留,**包括中文标点和括号里的枚举说明**——这正是它比手工整理靠谱的地方。 --- ## 4. 避坑指南:那些让我重装三次 MySQL 驱动才搞懂的边界问题 ### 4.1 现象:MySQL 8.0 连接报错 `Public Key Retrieval is not allowed` **原因**:MySQL 8.0 默认开启 `caching_sha2_password` 认证插件,而老版本 JDBC 驱动(< 8.0.28)未启用公钥检索。工具内置驱动版本若偏低,就会卡在这里。 **解决**: - 方案 A(推荐):升级 jar 包到 v2.3.0+,已内置 MySQL 8.0.33 驱动; - 方案 B:在 JDBC URL 末尾加参数 `&allowPublicKeyRetrieval=true&useSSL=false`; - 方案 C(治本):登录 MySQL,将 doc_reader 用户认证方式降级: ```sql ALTER USER 'doc_reader'@'%' IDENTIFIED WITH mysql_native_password BY 'your_secure_password'; FLUSH PRIVILEGES;

4.2 现象:PostgreSQL 表注释为空,字段注释正常

原因:PostgreSQL 的表级注释存储在pg_description系统表,但需关联pg_class和pg_namespace。某些精简版 PostgreSQL(如某些云厂商 RDS)可能未开启pg_catalog权限,或doc_reader账号缺少SELECT ON pg_description权限。
解决:

  • 给账号加权限(DBA 执行):
    GRANT SELECT ON pg_description TO doc_reader; GRANT SELECT ON pg_class TO doc_reader; GRANT SELECT ON pg_namespace TO doc_reader;
  • 或改用--sql-file模式,让 DBA 在导出 SQL 时用COMMENT ON TABLE user IS '用户主表';显式写出注释。

4.3 现象:Word 输出的表格文字挤在一起,没有换行

原因:Apache POI 对中文自动换行支持较弱,尤其当字段注释含长中文句(如COMMENT '订单状态:0-待支付,1-已支付,2-已发货,3-已完成,4-已取消,5-已退款'),POI 默认不折行。
解决:

  • 在配置文件config.yaml中增加word节点参数:
    word: auto-wrap: true # 启用单元格自动换行 font-size: 10 # 调小字号提升可读性 table-width-ratio: 0.95 # 表格占页面宽度比例,避免超宽
  • 更彻底:修改 Word 模板(company-template.docx),选中表格 → 右键「表格属性」→ 「单元格」→ 勾选「自动换行」。

4.4 现象:Oracle 数据库生成的字段类型全是VARCHAR2,丢失长度信息

原因:Oracle 的USER_TAB_COLUMNS.DATA_LENGTH返回字节长度,而DATA_TYPE为VARCHAR2时,实际字符长度需结合CHAR_USED='C'(字符语义)判断。旧版工具解析逻辑未区分字节/字符语义。
解决:

  • 升级到 v2.2.0+,已修复 Oracle 类型解析,能正确输出VARCHAR2(50 CHAR);
  • 若无法升级,临时方案:在 Oracle 中创建视图暴露字符长度:
    CREATE OR REPLACE VIEW docgen_columns AS SELECT table_name, column_name, data_type, CASE WHEN char_used = 'C' THEN data_length ELSE data_length/2 END AS char_length, nullable, comments FROM user_tab_cols t JOIN user_col_comments c USING(table_name,column_name);
    然后在配置中指定--sql-file用此视图生成。

4.5 现象:生成的 Markdown 中,TEXT类型字段显示为LONGTEXT,与实际不符

原因:MySQL 的TEXT、MEDIUMTEXT、LONGTEXT在information_schema.COLUMNS.COLUMN_TYPE中统一返回text,工具靠COLUMN_TYPE字段无法区分。
解决:

  • 工具 v2.3.0+ 已优化:改用information_schema.COLUMNS.EXTRA和COLUMN_COMMENT辅助判断,但最准的方式是查SHOW CREATE TABLE结果;
  • 强制使用--sql-file模式,确保原始 DDL 中类型名完整;
  • 或在配置中添加类型映射(高级用法):
    type-mapping: mysql: text: "TEXT" mediumtext: "MEDIUMTEXT" longtext: "LONGTEXT"

5. 进阶实战:把它塞进 GitLab CI,让每次 DDL 提交自动触发文档更新

5.1 场景还原:我们如何实现“代码即文档”的闭环

在某跨平台系统的 DevOps 流程中,数据库变更必须走 SQL 脚本管理:所有 DDL 存于./sql/migrations/目录,按V1.0.0__init.sql、V1.1.0__add_is_deleted_to_user.sql命名。过去靠人工跑 docgen,总有遗漏。现在,我们让 GitLab CI 在每次向main分支 push SQL 文件时,自动:

  1. 下载最新版 database-doc-generator;
  2. 解析本次提交新增/修改的 SQL 文件;
  3. 生成 Markdown 文档;
  4. 提交到docs/目录并推送到仓库。

这样,开发者git push完 SQL,10 分钟后在线文档站就刷新了新字段说明——文档和代码永远同 commit hash。

5.2 CI 配置文件详解:.gitlab-ci.yml关键片段

stages: - docgen generate-db-doc: stage: docgen image: openjdk:11-jre-slim before_script: - apt-get update && apt-get install -y curl unzip && rm -rf /var/lib/apt/lists/* - export DOCGEN_JAR="database-doc-generator-2.3.1.jar" - export DOCGEN_URL="https://github.com/xxx/database-doc-generator/releases/download/v2.3.1/${DOCGEN_JAR}" - curl -L ${DOCGEN_URL} -o ${DOCGEN_JAR} script: # 1. 找出本次 MR/commit 中变动的 SQL 文件 - | if [ "$CI_PIPELINE_SOURCE" = "merge_request_event" ]; then CHANGED_SQL=$(git diff --name-only $CI_MERGE_REQUEST_TARGET_BRANCH_NAME...$CI_COMMIT_SHA -- sql/migrations/*.sql | head -20) else CHANGED_SQL=$(git diff --name-only $CI_COMMIT_BEFORE_SHA $CI_COMMIT_SHA -- sql/migrations/*.sql | head -20) fi echo "Changed SQL files: $CHANGED_SQL" # 2. 若有变动,合并所有相关 SQL 到临时文件(避免单文件解析缺失外键上下文) - | if [ -n "$CHANGED_SQL" ]; then mkdir -p ./tmp-ddl cat $CHANGED_SQL > ./tmp-ddl/merged-ddl.sql # 3. 运行 docgen,输出到 docs/db/ java -jar ${DOCGEN_JAR} \ --sql-file ./tmp-ddl/merged-ddl.sql \ --output-format markdown \ --output-dir ./docs/db/ \ --verbose # 4. 提交生成的文档(仅当有改动) git config --global user.email "ci@example.com" git config --global user.name "GitLab CI" git add ./docs/db/ if git status --porcelain | grep -q '^M\|^A'; then git commit -m "[CI] Update DB docs for $(echo $CHANGED_SQL | tr '\n' ' ' | cut -c1-80)" git push https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git HEAD:${CI_DEFAULT_BRANCH} fi else echo "No SQL files changed, skip docgen." fi only: - main - merge_requests

关键点说明:

  • image: openjdk:11-jre-slim确保环境干净,无 JDK 版本冲突;
  • curl -L ${DOCGEN_URL}直接下载 release,避免构建缓存污染;
  • git diff ... -- sql/migrations/*.sql精准捕获 DDL 变更,不扫无关文件;
  • cat $CHANGED_SQL > merged-ddl.sql合并多文件,让工具能识别跨表外键(如order.user_id引用user.id);
  • git push https://gitlab-ci-token:${CI_JOB_TOKEN}@...使用 CI Token 推送,无需额外配置 deploy key。

5.3 文档质量守门员:在 CI 中加入字段注释覆盖率检查

光生成文档不够,还要保证质量。我们在 CI 中加了一道检查:所有非主键、非索引字段,必须有 COMMENT。否则 pipeline 失败,强制开发者补注释。

# 在 generate-db-doc job 的 script 末尾添加: - | # 检查生成的 Markdown 中,是否有字段缺失 COMMENT MISSING_COMMENT=$(grep -r "^\|.*\|.*\|.*\|.*\|.*\|$" ./docs/db/tables/ | grep -v "注释" | awk -F'\|' '{print $1,$2,$5}' | grep -E "\s+\|\s+\|\s+\$" | wc -l) if [ "$MISSING_COMMENT" -gt 0 ]; then echo "ERROR: Found $MISSING_COMMENT fields without COMMENT. Please add COMMENT to your DDL." echo "Example: \`name\` VARCHAR(50) NOT NULL COMMENT '用户名'," exit 1 fi

这段 Bash 会扫描所有tables/*.md文件,找那些第 5 列(注释列)为空的行。一旦发现,立即exit 1中断 pipeline,并给出修复示例。从那以后,我每次写 DDL,都强制在CREATE TABLE语句里敲完字段后,立刻补上COMMENT——不是因为流程要求,而是因为 CI 会红着脸告诉你:“这里缺注释,不许过”。

希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 8:10:36

Model Router:AI Agent 模型调用的自动挡设计与故障自愈实践

最近在打磨一个面向一线业务的智能助理项目&#xff08;内部代号叫 Pi Agent&#xff09;时&#xff0c;我有一半的时间都在跟模型调用较劲。这个 Agent 要处理的问题五花八门&#xff0c;有的请求就三五个字&#xff0c;比如“查一下订单状态”“明天什么天气”&#xff0c;有…

作者头像 李华
网站建设 2026/10/13 8:09:53

Kubernetes rollout 命令深度解析:掌控 Deployment 变更生命周期

1. 项目概述&#xff1a;为什么 rollout 是 Deployment 的“方向盘”而不是“开关”在 Kubernetes 生产环境中&#xff0c;我见过太多团队把kubectl apply -f deployment.yaml当作上线的全部动作——改完配置&#xff0c;一按回车&#xff0c;就去喝咖啡等结果。直到某天凌晨三…

作者头像 李华
网站建设 2026/10/13 8:09:03

Agent技能管理实战:从工具调用到标准化技能库设计

做智能体应用这一年多&#xff0c;我最大的感受是&#xff1a;模型底子已经不是最大的瓶颈&#xff0c;真正决定一个Agent能干多少活的&#xff0c;是它手里有多少靠谱的“技能”。许多项目前期跑demo都挺顺&#xff0c;一进真实场景就露馅——不是模型不聪明&#xff0c;是技能…

作者头像 李华
网站建设 2026/10/13 8:08:36

重排数字得到2的幂:频次统计替代全排列(力扣869)

平时刷题最怕看到“重排”两个字&#xff0c;因为一旦老老实实把全排列拉出来&#xff0c;基本就离超时不远了。LeetCode 869 这道题正好踩在这个痛点上&#xff1a;题目是 Reordered Power of 2&#xff0c;中文叫“重新排序得到 2 的幂”&#xff0c;标题里还带着“耗时100”…

作者头像 李华
网站建设 2026/10/13 8:08:24

低代码平台落地实战:需求拆解、选型要点与避坑指南

低代码近几年在企业圈里被反复提起&#xff0c;但真正把它用明白的团队其实不多。我见过有的公司上线低代码平台三个月就把核心业务流程跑通了&#xff0c;也见过有的团队选型两个月、试点半年&#xff0c;最后又退回传统开发的老路。差距不在工具本身&#xff0c;而在对低代码…

作者头像 李华
网站建设 2026/10/13 8:08:17

Linux系统优化策略:从启动到内核的全面调优指南

1. 为什么“系统优化”这件事值得认真对待很多人第一次接触Linux&#xff0c;都是从某个长期支持版本开始的。装完之后觉得能用&#xff0c;就再也没动过默认配置。直到某天发现开机要等一分多钟、硬盘灯狂闪、风扇呼呼转、终端敲个命令都要卡半秒&#xff0c;才意识到“能用”…

作者头像 李华