JavaProjectRepo/framework/docs/数据库初始方案.md

6.4 KiB
Raw Permalink Blame History

数据库初始方案framework

目标

  • framework 目录下建立 db-init 初始化目录,保存基础结构与基础数据。
  • 支持从 MySQL 导出一份“初始化用”的基线数据,并在应用启动时自动检测是否已初始化;若未初始化,自动导入。
  • 过程可重复、可审计、可在 devserver 环境下安全运行。

目录结构规划

  • framework/db-init/
    • sql/
      • base-schema.sql:基础库结构(表、索引、约束);可由 mysqldump --no-data 导出。
      • base-data.sql:初始化数据(字典、默认角色、管理员等);可由 mysqldump --no-create-info 导出或手写。
    • scripts/
      • export.ps1Windows 导出脚本PowerShell
      • import.ps1Windows 导入脚本PowerShell
      • export.shLinux/Mac 导出脚本(可选)。
      • import.shLinux/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 实现 ApplicationRunnerCommandLineRunnerDataInitializer
    • 启动时:检查标记 → 未初始化则依次执行 sql/base-schema.sqlsql/base-data.sql
    • SQL 执行方式:
      • 直接通过 JDBC 读取并执行 SQL 文件(分号切分、事务包裹、失败回滚)。
      • 或调用外部 mysql 命令(需服务器已安装 mysql 客户端,适合运维环境)。
    • Profile 控制:默认仅在 serverdev 首次运行时启用;可通过配置 app.init.enabled=true/false 控制。
  • 方案 B推荐中长期引入数据库版本管理工具
    • FlywayLiquibase 管理结构与数据变更;将初始化作为 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 则直接返回。
    • 使用 JdbcTemplateEntityManager 查询 marker-table 状态。
    • 若未初始化:
      • 读取并执行 schemadata 指定的 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。