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

134 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据库初始方案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。