用户登录
个人主页 用户中心 我的订单 添加授权 管理授权
退出登录
用户登录 用户注册
欢迎来到 UC建站系统

数据库批量脚本生成工具,反向生成建表SQL、批量给100张表加审计字段、3秒生成全库CRUD存储过程,这三种场景不靠工具手写到天亮

接手过一个老项目,数据库里187张表,没有建表脚本、没有文档、没有ER图,字段注释全靠猜。运维要求所有表加created_at/updated_at/deleted三个审计字段,再加对应的索引。如果一张张手动写ALTER TABLE,光拼字段名就能拼到凌晨三点。后来发现有一套工具组合能在五分钟内搞定——反向生成全库DDL、批量修改表结构、自动生成存储过程,把187张表的活从三天压缩到五分钟。

数据库批量脚本生成这个需求,拆开来其实是五个子场景:从现有数据库反向生成建表脚本、根据表结构批量生成CRUD存储过程、批量修改表结构(加字段/索引/触发器)、不同数据库之间做DDL转换(MySQL转PostgreSQL之类)、以及批量生成测试数据。每个场景都有对应的工具,没有哪一个工具能全搞定,但组合起来能省掉80%的手写SQL时间。

五种批量脚本生成场景,对号入座找工具

1反向生成DDL — 已有数据库但没有建表脚本,需要导出全库建表语句
2批量生成CRUD存储过程 — 根据表结构自动生成增删改查存储过程,避免手写重复SQL
3批量修改表结构 — 给几十上百张表统一加字段、索引、触发器、注释
4数据库迁移DDL转换 — MySQL转PostgreSQL、SQL Server转MySQL,语法差异自动适配
5批量生成测试数据 — 按表结构自动填充符合字段类型的假数据,用于性能测试和开发调试

一、反向生成DDL,数据库搬家第一关

反向生成建表脚本是最基础也是最刚需的场景。数据库跑了好几年,原始建表脚本早不知道丢哪了,现在要做环境迁移、要做灾难恢复演练、或者单纯想留一份全库DDL做版本管理。MySQL自带的mysqldump --no-data能导出建表语句,但导出来的内容夹杂着大量AUTO_INCREMENT值、字符集声明、引擎声明,直接拿去另一个环境跑往往报错。

mysqldump导出纯DDL的清理版命令

mysqldump -h主机 -u用户 -p --no-data --skip-add-drop-table --skip-comments --compact 数据库名 > schema.sql

--skip-add-drop-table 去掉DROP TABLE(迁移到已有库时避免误删),--skip-comments 去掉注释噪音,--compact 压缩输出格式。

但mysqldump只是一个导出工具,不算"生成"工具。真正能做反向生成的有两类:一类是数据库客户端内置的DDL导出功能,另一类是专门的Schema逆向工具。

1 - 数据库批量脚本生成工具,反向生成建表SQL、批量给100张表加审计字段、3秒生成全库CRUD存储过程,这三种场景不靠工具手写到天亮 - UC建站系统

工具类型支持的数据库核心能力费用
DBeaver客户端内置MySQL/PG/SQL Server/Oracle等90+右键库→生成SQL→选DDL,一键导出全库建表脚本,自动处理外键依赖顺序免费
SchemaSpy独立工具主流关系型数据库反向生成ER图+HTML文档+建表DDL,表关系一目了然免费
Navicat客户端内置MySQL/PG/SQLite/Oracle等数据传输→仅结构,跨数据库类型直接转换DDL语法付费(约$200/年)
dbdocs.io在线SaaS通过DBML中间语言支持多种DB导入DDL→自动生成可视化文档→团队共享链接,适合给非技术人员看表结构免费版有限制

DBeaver在这个场景下是最实用的——免费、支持数据库种类多、操作简单。187张表选中数据库右键"生成SQL",勾选"CREATE TABLE"和"外键",三秒生成完整DDL。唯一要注意的是外键依赖顺序:如果A表外键引用B表,建表脚本必须先建B表再建A表,否则执行报错。DBeaver会自动处理这个顺序,但mysqldump不会——导出的建表语句顺序是按表名排序的,不是按依赖关系排序。

二、批量生成CRUD存储过程,把重复代码交给脚本

一个典型的业务系统,每张表都需要四个基础存储过程:Insert、UpdateById、SelectById、DeleteById(软删除或物理删除)。50张表就是200个存储过程,手写的话不仅枯燥,而且容易出现字段遗漏——某张表加了一个字段,忘记在Update存储过程中加对应的参数和SET语句,线上排查半天才发现问题。

存储过程生成工具的原理很简单:读取information_schema.columns获取表的所有字段名和类型,然后按模板拼SQL字符串。但不同工具的实现深度差异很大——有的只是简单拼接字段列表,有的能处理自增主键跳过、默认值识别、乐观锁版本号、JSON字段特殊处理等边界情况。

MyBatis Generator (MBG)

Java生态最成熟的代码生成器。根据数据库表反向生成:实体类、Mapper接口、XML映射文件(含完整CRUD)、Example动态查询类。配置文件指定哪些表、生成到哪个包、是否生成注释。支持分页插件和自定义注释模板。MySQL/PG/Oracle/SQL Server全覆盖,Maven插件或命令行运行。

sqlautoreview + 存储过程模板

适合纯SQL场景。读取information_schema后用Python/Jinja2模板引擎生成存储过程。关键代码不到100行:连接数据库→查columns表→Jinja2渲染模板→输出.sql文件。可以自定义模板内容,比如在Update过程中加updated_at = NOW()、在Delete中改成软删除SET is_deleted = 1。

dbForge SQL Complete

SQL Server生态的智能补全+脚本生成工具。右键数据库选"Script Database",一键生成全库CRUD存储过程。自动处理IDENTITY列跳过、TIMESTAMP列处理、计算列排除。付费($199/年),但SQL Server开发场景效率提升明显。

自定义Python脚本

最灵活的方案,适合有特殊需求(如生成带审计字段的存储过程、生成分页查询存储过程)。核心思路:PyMySQL连库→SELECT COLUMN_NAME, DATA_TYPE, COLUMN_KEY FROM information_schema.COLUMNS→用f-string或模板引擎拼接SQL→写入文件。半天写完脚本,之后每次表结构变更重新跑一次即可。

Python批量生成存储过程的核心思路

用不到100行Python脚本,连接数据库读取每张表的字段信息,然后按模板生成INSERT/UPDATE/SELECT/DELETE四个存储过程。关键是要处理自增主键不参与INSERT、TIMESTAMP字段不参与UPDATE、软删除改成SET is_deleted = 1而不是真删。

import pymysqlfrom jinja2 import Template# 连接数据库,获取所有表名conn = pymysql.connect(host='localhost', user='root', password='', db='mydb')cursor = conn.cursor()cursor.execute("SHOW TABLES")tables = [row[0] for row in cursor.fetchall()]# 存储过程模板proc_template = Template("""CREATE PROCEDURE sp_{{ table }}_insert({% for col in columns if col['key'] != 'PRI' %}IN p_{{ col['name'] }} {{ col['type'] }}{% if not loop.last %},{% endif %}{% endfor %})BEGININSERT INTO {{ table }}({% for col in columns if col['key'] != 'PRI' %}{{ col['name'] }}{% if not loop.last %}, {% endif %}{% endfor %})VALUES({% for col in columns if col['key'] != 'PRI' %}p_{{ col['name'] }}{% if not loop.last %}, {% endif %}{% endfor %});END;""")for table in tables:cursor.execute(f"SELECT COLUMN_NAME, DATA_TYPE, COLUMN_KEY FROM information_schema.COLUMNS WHERE TABLE_NAME='{table}'")columns = [{'name': r[0], 'type': r[1], 'key': r[2]} for r in cursor.fetchall()]# 生成4个存储过程: insert, update_by_id, select_by_id, delete_by_idwith open(f'sp_{table}.sql', 'w') as f:f.write(proc_template.render(table=table, columns=columns))

用模板生成存储过程的好处是一致性——全库200个存储过程的参数命名规则、错误处理方式、事务控制写法完全统一。后期维护时不用去猜每个存储过程是谁写的、用了什么风格。而且模板改一次,重新跑一遍脚本,全库存储过程全部更新。

三、批量修改表结构,100张表加字段不是噩梦

回到开头那个187张表的场景:每张表加三个审计字段created_at/datetime、updated_at/datetime、deleted_at/datetime/nullable,再加两个索引idx_created_at和idx_deleted。如果手写就是187×5=935行ALTER TABLE语句,拼写错误的概率极高。

批量ALTER TABLE的核心SQL——一条SELECT生成所有语句

SELECT CONCAT('ALTER TABLE ', TABLE_NAME, ' ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT ''创建时间'', ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ''更新时间'', ADD COLUMN deleted_at DATETIME DEFAULT NULL COMMENT ''删除时间'';') AS alter_sql FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_db' AND TABLE_TYPE = 'BASE TABLE';

执行这条SQL,会输出187条完整的ALTER TABLE语句。复制结果到新查询窗口执行即可。但注意:大表加字段会锁表,线上环境要在凌晨低峰期执行,或者用pt-online-schema-change做在线DDL。

用information_schema拼SQL是最简单粗暴的方式,但有几个细节要注意。加索引的SQL需要单独拼,不能和加字段放在同一个ALTER TABLE里(虽然语法允许,但分开执行出错时更容易定位)。另外如果某些表已经有了created_at字段,再执行ADD COLUMN会报Duplicate column错误,需要加一个NOT EXISTS判断——查information_schema.COLUMNS确认字段是否已存在,过滤掉已有字段的表。

批量修改类型SQL生成方式注意事项
加字段SELECT CONCAT + information_schema.TABLES先查COLUMNS表确认字段不存在,避免Duplicate column;大表建议用pt-osc在线DDL
加索引SELECT CONCAT + information_schema.STATISTICS做NOT EXISTS过滤线上加索引会锁表,用ALGORITHM=INPLACE, LOCK=NONE;先EXPLAIN确认索引有效再批量加
修改字段类型SELECT CONCAT + information_schema.COLUMNS读取当前类型VARCHAR改TEXT、INT改BIGINT要评估数据兼容性;建议先导出数据→改表→导入验证
统一字符集SELECT CONCAT + information_schema.TABLES/COLUMNS表和字段的字符集要一起改;改字符集会重建表,大表慎重
批量加注释SELECT CONCAT + information_schema.COLUMNS,用CASE WHEN按字段名匹配注释注释最好有统一的命名规范,如"用户ID|关联users表";生成后建议导出到Excel让业务方确认

批量ALTER TABLE最容易犯的三个错误

· 在一条ALTER TABLE里加字段+加索引+改字符集,执行失败后回滚不完整,导致部分变更生效部分未生效。拆成多条独立语句。

· 没有先查COLUMNS表就执行ADD COLUMN,遇到已有字段直接报错中断,后面的表都没执行到。

· 生产环境执行ALTER TABLE前不检查表大小。一张5000万行的表加字段可能锁表10分钟,业务直接挂掉。先用SELECT TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES排个序,大表标记出来单独处理。

四、数据库迁移DDL转换,MySQL到PostgreSQL不是改个类型名那么简单

数据库迁移时最头疼的不是数据迁移,而是DDL转换。MySQL的AUTO_INCREMENT到PostgreSQL要变成SERIAL/BIGSERIAL,TINYINT在PostgreSQL里没有对应类型要用SMALLINT替代,ENGINE=InnoDB在PostgreSQL里根本没这个概念,CHARSET=utf8mb4要对应到PostgreSQL的数据库级别编码设置。一个200张表的数据库手动改写DDL,光类型映射就能出错几十处。

pgloader

专门做MySQL→PostgreSQL迁移的开源工具。自动处理类型映射、索引重建、外键转换。一条命令完成全库迁移:pgloader mysql://user:pass@host/db postgresql://user:pass@host/db。支持断点续传和增量同步。唯一不足是对MySQL存储过程和触发器的转换不完美,需要手动检查。

SQLines SQL Converter

在线DDL转换工具,支持MySQL↔PostgreSQL↔SQL Server↔Oracle等双向转换。贴入DDL,选择源和目标数据库类型,一键转换。免费在线版限制每次5000字符,大库要分段粘贴。支持批量文件转换的离线版需付费($290起)。

AWS DMS Schema Conversion

AWS Database Migration Service自带的Schema转换工具。自动评估源库和目标库的兼容性,生成转换报告指出哪些对象无法自动转换。适合上云迁移场景,支持MySQL→Aurora PostgreSQL等AWS生态内转换。非AWS环境用不了。

Navicat数据传输

Navicat的数据传输功能支持跨数据库类型的结构和数据同步。选择源库和目标库,勾选"仅结构",自动完成类型映射和DDL转换。对于字段类型映射不准确的情况,可以在传输前手动编辑映射规则。付费但GUI操作比命令行直观很多。

DDL转换工具能解决80%的类型映射问题,但剩下的20%需要人工介入。常见的坑包括:MySQL的UNSIGNED INTEGER到PostgreSQL没有直接对应类型,需要用CHECK约束替代;MySQL的ENUM类型在PostgreSQL中要改为VARCHAR加CHECK约束或使用自定义枚举类型;MySQL的ON UPDATE CURRENT_TIMESTAMP在PostgreSQL中需要用触发器实现。转换后一定要在测试环境完整跑一遍建表脚本,确认没有报错。

五、批量生成测试数据,性能测试和开发联调的刚需

开发环境需要测试数据、性能测试需要百万级数据、客户演示需要看起来真实的数据。手写INSERT语句造数据是最笨的办法——100万行数据要写100万条INSERT,而且手写的数据太规整(全是"张三""测试数据""13800138000"),查询优化器看到这种数据生成的执行计划跟线上完全不一样。

工具数据生成方式特色适合场景
Mockaroo在线可视化配置,拖拽选择字段类型和生成规则200+字段类型预设,自动识别字段名匹配生成规则(email字段自动生成邮箱格式),支持导出SQL/CSV/JSON小批量(1000行内免费)、需要真实感数据的开发联调
dbForge Data Generator读取表结构自动匹配生成器,支持外键关联数据一致性自动识别外键关系生成关联数据,支持正态分布/随机分布等多种数据分布模式SQL Server/MySQL大数量级测试数据生成
Python Faker库代码控制,完全自定义pip install faker,三行代码开始生成。支持中文(zh_CN),姓名/地址/电话/公司名都像真的。批量INSERT用executemany提升速度需要高度定制数据规则、批量百万级、自动化CI/CD集成
sysbench命令行批量生成压测数据sysbench oltp_read_write prepare 一键生成标准压测表+数据,适合数据库性能基准测试数据库性能压测,不是业务测试数据
from faker import Fakerimport pymysqlimport randomfake = Faker('zh_CN')conn = pymysql.connect(host='localhost', user='root', password='', db='test')cursor = conn.cursor()# 读取表结构,自动匹配Faker生成规则cursor.execute("SELECT COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_NAME='users'")columns = cursor.fetchall()# 批量生成10万条,用executemany一次提交data = []for _ in range(100000):row = []for col_name, col_type in columns:if 'name' in col_name:row.append(fake.name())elif 'email' in col_name:row.append(fake.email())elif 'phone' in col_name or 'mobile' in col_name:row.append(fake.phone_number())elif 'address' in col_name:row.append(fake.address())elif 'company' in col_name:row.append(fake.company())elif 'int' in col_type:row.append(random.randint(1, 99999))elif 'datetime' in col_type or 'timestamp' in col_type:row.append(fake.date_time_between('-2y', 'now'))else:row.append(fake.text()[:50])data.append(tuple(row))cursor.executemany("INSERT INTO users VALUES (" + ",".join(["%s"]*len(columns)) + ")", data)conn.commit()

Faker做测试数据生成的优势是可控性强。Mockaroo在线版免费额度只有1000行,Faker跑100万行也就几分钟。而且可以精确控制数据分布——比如order表里70%的订单是已支付、20%已发货、8%已完成、2%已退款,用random.choices加权重即可。这种分布控制对于模拟真实线上场景做性能测试非常关键。

六、ORM代码生成器和SQL脚本生成器的区别

很多开发分不清这两类工具,以为MyBatis Generator和存储过程生成器是一回事。其实面向的对象完全不同。

2 - 数据库批量脚本生成工具,反向生成建表SQL、批量给100张表加审计字段、3秒生成全库CRUD存储过程,这三种场景不靠工具手写到天亮 - UC建站系统

ORM代码生成器

· 生成Java/C#/Python等应用层代码

· 输出:Entity类、Mapper、Repository、DTO

· 调用链:Controller→Service→Mapper→SQL

· 代表:MyBatis Generator、JHipster、Entity Framework Scaffold

· 适合:前后端分离项目、微服务架构

SQL脚本生成器

· 生成纯SQL:DDL、DML、存储过程、函数

· 输出:.sql文件,直接在数据库执行

· 调用链:应用→存储过程→数据库

· 代表:information_schema拼SQL、pgloader、自定义模板脚本

· 适合:存储过程为主的架构、数据库迁移、DBA运维

很多项目两者都用。MyBatis Generator生成Java层的增删改查代码,再配合Python脚本生成数据库层的存储过程和视图。但要注意两者生成的SQL要保持一致——Mapper XML里手写的SQL和存储过程如果逻辑不同,排查起来非常痛苦。比较好的做法是统一从存储过程调用,Mapper只做简单的存储过程调用封装,这样SQL逻辑只在存储过程里维护一份。

七、三个容易被忽略但非常重要的问题

问题一:批量脚本生成后的SQL必须逐条review

工具生成的脚本是机械拼装的,不会理解业务含义。比如一张order表的user_id字段,工具生成的Update存储过程允许修改user_id——这在业务上是错误的,一个订单的用户不应该被修改。这类业务约束需要在生成后手动调整。建议生成脚本后先全文搜索DROP、DELETE、TRUNCATE,确认没有误生成破坏性操作。

问题二:不同数据库的information_schema结构不一样

用information_schema拼SQL是通用思路,但MySQL、PostgreSQL、SQL Server的information_schema字段名和表名有差异。MySQL用TABLES.TABLE_SCHEMA过滤库名,PostgreSQL用table_schema(小写),SQL Server用TABLE_CATALOG。如果要写一个通用的批量脚本生成工具,数据库适配层至少要处理这些差异。

问题三:生成的脚本要纳入版本管理

批量生成的DDL和存储过程脚本,生成完就扔到服务器上执行,下次表结构变了又要重新生成。正确的做法是把生成的脚本放到Git仓库里,和Flyway/Liquibase这类数据库迁移工具配合使用。每次表结构变更后重新生成脚本→对比diff→只提交变更部分→通过CI/CD自动执行。这样数据库变更就有了完整的版本历史和回滚能力。

八、站群场景下的数据库批量管理

有一个特殊场景值得单独拿出来说:做站群的时候,每个站点独立部署一套数据库,50个站点就是50套数据库。当需要统一修改表结构时——比如所有站点的文章表加一个"AI生成标记"字段——如果一个个登录数据库执行ALTER TABLE,工作量跟187张表加字段一样让人崩溃。

这个场景的解法是写一个批量执行脚本:维护一个站点数据库连接列表,遍历每个连接执行相同的DDL语句,输出执行日志到文件。如果50个站点的表结构完全一致(这在站群场景里很常见),批量DDL的执行效率极高——50个ALTER TABLE并行跑,全部完成也就是几秒到十几秒的事。

单站手动执行

50分钟

50个站 × 1分钟/站

批量脚本并行

12秒

50个连接并行执行

错误率对比

0 vs 5%

脚本0拼写错误 vs 手动总有漏

执行日志

完整

每个站的成功/失败/耗时全记录

如果用的是UC建站系统这类WP底层架构,50个站点虽然各自独立数据库,但表结构天然统一——都是WordPress标准表结构(wp_posts、wp_postmeta、wp_options等)。这种场景下批量DDL的脚本更加标准化:维护一个站点列表JSON配置文件,脚本遍历列表执行统一SQL,通过多站看板统一监控每个站点数据库的执行状态和异常情况。

做个表格把本文提到的工具和场景串起来,方便对号入座。

你要做的事首选工具备选方案费用
从现有数据库导出全库建表脚本DBeaver右键生成SQLmysqldump --no-data + 手工清理免费
根据表结构生成CRUD存储过程Python + Jinja2自定义脚本MyBatis Generator(Java栈)、dbForge(SQL Server)免费
给100张表统一加字段和索引SELECT CONCAT拼SQLPython脚本遍历information_schema免费
MySQL DDL转PostgreSQL DDLpgloaderSQLines在线转换、Navicat数据传输免费/$290起/$200年
批量生成100万行测试数据Python Faker + executemanyMockaroo(小批量)、dbForge Data Generator(付费)免费
批量生成Java实体类和MapperMyBatis GeneratorJHipster、IDEA内置Generate POJO免费
50个站点统一改表结构Python批量连接脚本Ansible + mysql模块免费
生成ER图+数据库文档SchemaSpydbdocs.io、DBeaver ER图免费

数据库批量脚本生成这件事,核心思路就一条:能读information_schema就别手写,能模板化就别逐行拼,能并行跑就别串行等。187张表的手写SQL噩梦说到底不是体力问题,是没有把重复劳动交给工具的意识。information_schema是数据库自带的元数据中心,所有的表名、字段名、字段类型、索引、外键都在里面,批量生成脚本的本质就是从这张元数据表里读数据、按模板渲染、输出SQL文件。搞懂了这一层,不管是要生成建表DDL、存储过程、测试数据还是迁移脚本,思路都是一样的——读元数据→拼模板→批量输出。

最后说一句:工具生成的脚本在执行前至少要做两件事——全文搜索DROP和DELETE确认没有误生成破坏性语句,在测试库先跑一遍确认无报错。批量脚本效率高是把双刃剑,生成快意味着出错的覆盖面也大,187张表一起执行错了想回滚可不是开玩笑的。

相关推荐
在线客服
👇找客服拿折扣
QQ咨询&售后
在线时间
11:00 ~ 5:30
QQ:3155555535
👇联系QQ
👇联系WX
首页 程序 帮助 登录