6.4 KiB
6.4 KiB
数据库初始方案(framework)
目标
- 在
framework目录下建立db-init初始化目录,保存基础结构与基础数据。 - 支持从 MySQL 导出一份“初始化用”的基线数据,并在应用启动时自动检测是否已初始化;若未初始化,自动导入。
- 过程可重复、可审计、可在
dev与server环境下安全运行。
目录结构规划
framework/db-init/sql/base-schema.sql:基础库结构(表、索引、约束);可由mysqldump --no-data导出。base-data.sql:初始化数据(字典、默认角色、管理员等);可由mysqldump --no-create-info导出或手写。
scripts/export.ps1:Windows 导出脚本(PowerShell)。import.ps1:Windows 导入脚本(PowerShell)。export.sh:Linux/Mac 导出脚本(可选)。import.sh:Linux/Mac 导入脚本(可选)。
README.md:说明如何导出/导入、注意事项与环境变量。
MySQL 导出策略
- 推荐使用
mysqldump分离结构与数据,以便初始化时灵活控制:- 结构:
mysqldump -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD --no-data --databases $DB_NAME > sql/base-schema.sql - 数据:
mysqldump -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD --no-create-info --databases $DB_NAME --tables <白名单表> > sql/base-data.sql
- 结构:
- 数据白名单建议包含:
- 字典/配置表(如
sys_dict,sys_config) - 权限/角色/菜单(如
sys_user(仅管理员)、sys_role,sys_menu,sys_user_role,sys_role_menu) - 地区或静态映射表(如有)
- 字典/配置表(如
- 机密信息与动态数据不导出:
- 排除审计日志、任务运行记录、业务动态表等。
导入策略
- 应用启动时进行“初始化检测”:
- 建议引入标记表:
app_init(单行),字段initialized boolean,version varchar,或在sys_config中维护init_done键。 - 检测逻辑:
- 若标记不存在或值为
false,视为未初始化。 - 若存在且为
true,跳过初始化。
- 若标记不存在或值为
- 建议引入标记表:
- 导入步骤(未初始化时):
- 执行
base-schema.sql(若目标库为空或需校正结构时)。 - 执行
base-data.sql(插入/更新缺失的基线数据,注意幂等性)。 - 更新标记为已初始化,并记录版本与时间戳。
- 执行
- 幂等性建议:
- 数据插入使用“存在则跳过/更新”策略(
INSERT ... ON DUPLICATE KEY UPDATE或先查询再写入)。 - 避免覆盖已有业务数据;仅在缺失时补充。
- 数据插入使用“存在则跳过/更新”策略(
Spring Boot 集成方案
- 方案 A(轻量):在后端增加初始化 Runner
- 新增一个
@Component实现ApplicationRunner或CommandLineRunner的DataInitializer。 - 启动时:检查标记 → 未初始化则依次执行
sql/base-schema.sql与sql/base-data.sql。 - SQL 执行方式:
- 直接通过 JDBC 读取并执行 SQL 文件(分号切分、事务包裹、失败回滚)。
- 或调用外部
mysql命令(需服务器已安装mysql客户端,适合运维环境)。
- Profile 控制:默认仅在
server或dev首次运行时启用;可通过配置app.init.enabled=true/false控制。
- 新增一个
- 方案 B(推荐中长期):引入数据库版本管理工具
Flyway或Liquibase管理结构与数据变更;将初始化作为V1__base.sql脚本。- 优点:变更有版本与校验,部署一致性更强;缺点:需要改造现有 SQL 并纳入流水线。
配置示例
application-server.yml中添加:
app:
init:
enabled: true
schema: classpath:db-init/sql/base-schema.sql
data: classpath:db-init/sql/base-data.sql
marker-table: app_init
marker-version: v1.0.0
- 路径策略:
- 若以资源方式打包,建议将
db-init/sql复制到src/main/resources/db-init/sql。 - 或保留在项目根并通过绝对/相对路径访问(需考虑部署路径与权限)。
- 若以资源方式打包,建议将
脚本示例(Windows PowerShell)
framework/db-init/scripts/export.ps1
param(
[string]$DB_HOST = "43.138.168.68",
[int]$DB_PORT = 3306,
[string]$DB_NAME = "frameworkdb2025",
[string]$DB_USER = "root",
[string]$DB_PASSWORD = "ylfw20230626@"
)
$env:MYSQL_PWD = $DB_PASSWORD
# 导出结构
mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER --no-data --databases $DB_NAME > ../sql/base-schema.sql
# 按需导出数据(示例表名可调整)
mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER --no-create-info $DB_NAME sys_dict sys_config sys_role sys_menu sys_user sys_user_role sys_role_menu > ../sql/base-data.sql
Write-Host "Export completed: base-schema.sql & base-data.sql"
framework/db-init/scripts/import.ps1
param(
[string]$DB_HOST = "127.0.0.1",
[int]$DB_PORT = 3306,
[string]$DB_NAME = "platform",
[string]$DB_USER = "root",
[string]$DB_PASSWORD = "root"
)
$env:MYSQL_PWD = $DB_PASSWORD
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER $DB_NAME < ../sql/base-schema.sql
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER $DB_NAME < ../sql/base-data.sql
Write-Host "Import completed"
启动时自动初始化的实现建议(代码思路)
- 创建
DataInitializer:- 读取
app.init.enabled;若为false则直接返回。 - 使用
JdbcTemplate或EntityManager查询marker-table状态。 - 若未初始化:
- 读取并执行
schema、data指定的 SQL 文件;分批执行并开启事务。 - 写入标记表
initialized=true, version=marker-version, ts=now()。
- 读取并执行
- 读取
- 并发保护:
- 使用数据库锁或单例启动(例如基于
SELECT ... FOR UPDATE或分布式锁)避免多实例重复初始化。
- 使用数据库锁或单例启动(例如基于
- 失败回滚与告警:
- 执行失败时回滚事务并记录日志,提示人工介入;避免部分写入。
运维与审计
- 对
sql/base-data.sql的修改应评审并走 PR,避免带入敏感数据。 - CI 提示:
- 在
server构建流水线中,可增加“初始化脚本语法检查”(如用mysql --dry-run或解析器)。
- 在
- 版本管理:
- 在
db-init/README.md中记录每次更新目的与影响;或使用Flyway版本号管理。
- 在
下一步落地
- 我可以为你:
- 搭建
framework/db-init目录与示例脚本、README。 - 在后端新增
DataInitializer组件与配置项,支持dev/server下自动初始化。 - 可选集成
Flyway,将初始化脚本迁移为V1__base.sql并接入 CI。
- 搭建