Files
schoolNews/docker/init-db/数据库初始化指南.md
2025-11-24 11:50:15 +08:00

8.4 KiB
Raw Blame History

Docker环境数据库初始化指南

📋 概述

本指南说明如何为Docker环境准备数据库初始化脚本参考 schoolNewsServ/.bin/mysql/sql/reInit.sh 的实现。

🎯 初始化流程

MySQL容器启动流程

Docker容器启动
   ↓
执行 /docker-entrypoint-initdb.d/ 中的脚本(按字母顺序)
   ↓
01-init-database.sql    → 创建数据库和初始化标记表
   ↓
02-create-tables.sql    → 创建所有业务表
   ↓
03-init-data.sql        → 导入初始数据
   ↓
数据库就绪

📂 文件说明

现有文件

文件 说明 状态
01-init-database.sql 创建数据库和_db_init_status表 已存在
README.md 数据库初始化说明 已存在

需要准备的文件

文件 说明 来源
02-create-tables.sql 所有表结构 从 createTable*.sql 合并
03-init-data.sql 初始数据 从 init*.sql 合并

🔧 准备方法

方式1: 使用自动脚本(推荐)

cd docker/init-db
chmod +x prepare-sql.sh
./prepare-sql.sh

脚本会自动:

  1. 备份现有SQL文件
  2. 合并所有createTable*.sql到02-create-tables.sql
  3. 合并所有init*.sql到03-init-data.sql
  4. 添加Docker特定配置爬虫路径等
  5. 生成统计信息

方式2: 手动复制

步骤1: 准备表结构

cd schoolNewsServ/.bin/mysql/sql

# 合并所有createTable*.sql
cat createTableUser.sql \
    createTablePermission.sql \
    createTablePermissionControl.sql \
    createTableResource.sql \
    createTableCourse.sql \
    createTableLearning.sql \
    createTableUserCenter.sql \
    createTableAI.sql \
    createTableSystem.sql \
    createTableAchievement.sql \
    createTableCrontab.sql \
    createTableMessage.sql \
    createTableSensitive.sql \
    > ../../docker/init-db/02-create-tables.sql

步骤2: 准备初始数据

# 合并所有init*.sql
cat initMenuData.sql \
    initAllData.sql \
    initCrontabMetaData.sql \
    > ../../docker/init-db/03-init-data.sql

步骤3: 添加Docker配置

03-init-data.sql 末尾添加:

-- Docker环境爬虫配置
INSERT IGNORE INTO tb_sys_config (config_key, config_value, config_desc, created_at) 
VALUES 
    ('crawler.pythonPath', '/usr/bin/python3', 'Docker容器内Python路径', NOW()),
    ('crawler.basePath', '/app/crawler', 'Docker容器内爬虫脚本路径', NOW());

🔍 脚本内容说明

initAll.sql 结构

基于 schoolNewsServ/.bin/mysql/sql/initAll.sql:

-- 1. 创建数据库
SOURCE createDB.sql;

-- 2-14. 创建各模块表
SOURCE createTableUser.sql;
SOURCE createTablePermission.sql;
SOURCE createTablePermissionControl.sql;
SOURCE createTableResource.sql;
SOURCE createTableCourse.sql;
SOURCE createTableLearning.sql;
SOURCE createTableUserCenter.sql;
SOURCE createTableAI.sql;
SOURCE createTableSystem.sql;
SOURCE createTableAchievement.sql;
SOURCE createTableCrontab.sql;
SOURCE createTableMessage.sql;
SOURCE createTableSensitive.sql;

-- 15-17. 插入初始数据
SOURCE initMenuData.sql;
SOURCE initAllData.sql;
SOURCE initCrontabMetaData.sql;

各模块说明

模块 表数量 说明
User 3+ 用户、部门、角色
Permission 10+ 菜单、权限、角色权限
Resource 5+ 资源、标签、分类
Course 3+ 课程、章节、课件
Learning 5+ 学习记录、笔记
UserCenter 3+ 个人中心、收藏、评论
AI 5+ AI智能体、对话
System 5+ 系统配置、日志
Achievement 5+ 成就系统
Crontab 3+ 定时任务
Message 3+ 消息通知
Sensitive 1+ 敏感词

⚠️ 重要注意事项

1. SOURCE语句不支持

Docker的mysql镜像初始化不支持 SOURCE 语句:

-- ❌ 不支持
SOURCE createTableUser.sql;

-- ✅ 需要合并成一个文件
-- 将所有SQL内容直接写入
CREATE TABLE tb_user (...);
CREATE TABLE tb_role (...);

2. 幂等性设计

确保脚本可以重复执行:

-- 使用IF NOT EXISTS
CREATE TABLE IF NOT EXISTS tb_user (...);

-- 使用INSERT IGNORE
INSERT IGNORE INTO tb_sys_config VALUES (...);

-- 检查执行状态
SET @executed = (SELECT COUNT(*) FROM _db_init_status WHERE script_name = '02-create-tables.sql');

3. 执行顺序

文件按字母顺序执行,因此命名很重要:

01-init-database.sql    (首先执行)
02-create-tables.sql    (其次执行)
03-init-data.sql        (最后执行)

4. 字符集配置

确保使用UTF-8MB4

CREATE TABLE tb_xxx (
    ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

🧪 测试验证

1. 检查SQL文件

# 查看文件大小
ls -lh docker/init-db/*.sql

# 检查SQL语法
cd docker/init-db
mysql --help | grep "Default options"

2. 本地测试

# 在本地MySQL测试
mysql -uroot -p123456 < docker/init-db/01-init-database.sql
mysql -uroot -p123456 < docker/init-db/02-create-tables.sql
mysql -uroot -p123456 < docker/init-db/03-init-data.sql

3. Docker环境测试

# 删除旧数据
docker-compose down -v

# 启动MySQL
docker-compose up -d mysql

# 查看初始化日志
docker logs school-news-mysql 2>&1 | grep -E "init|sql"

# 检查数据库
docker exec school-news-mysql mysql -uroot -p123456 -e "SHOW DATABASES;"
docker exec school-news-mysql mysql -uroot -p123456 school_news -e "SHOW TABLES;"

# 检查默认用户
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
"SELECT username, nickname FROM tb_sys_user WHERE username='admin';"

4. 验证初始化状态

# 查看初始化记录
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
"SELECT * FROM _db_init_status ORDER BY executed_at;"

# 统计表数量
docker exec school-news-mysql mysql -uroot -p123456 school_news -e \
"SELECT COUNT(*) AS table_count FROM information_schema.tables WHERE table_schema='school_news';"

🔄 更新数据库结构

场景1: 本地开发添加了新表

  1. schoolNewsServ/.bin/mysql/sql/ 中创建SQL文件
  2. 更新 initAll.sql 添加SOURCE语句
  3. 重新运行 prepare-sql.sh
  4. 重新构建Docker镜像

场景2: 修改现有表结构

  1. 创建迁移脚本 04-migration-xxx.sql
  2. 放入 docker/init-db/ 目录
  3. 脚本会自动执行(按字母顺序)

示例迁移脚本:

-- 04-migration-add-column.sql
USE school_news;

-- 检查是否已执行
SET @executed = (SELECT COUNT(*) FROM _db_init_status WHERE script_name = '04-migration-add-column.sql');

-- 添加新列
ALTER TABLE tb_user ADD COLUMN IF NOT EXISTS new_column VARCHAR(255);

-- 记录执行
INSERT IGNORE INTO _db_init_status (script_name) VALUES ('04-migration-add-column.sql');

📊 默认数据说明

默认用户

用户名 密码 角色 说明
admin admin123 管理员 超级管理员账号

默认角色

角色 说明
admin 管理员,拥有所有权限
freedom 自由角色,基础权限

默认部门

部门 说明
root_department 超级部门
default_department 默认部门

系统配置

配置项 说明
crawler.pythonPath /usr/bin/python3 Python路径
crawler.basePath /app/crawler 爬虫脚本路径

🛠️ 故障排查

问题1: 初始化脚本未执行

症状: 数据库创建了但表不存在

排查:

# 查看MySQL日志
docker logs school-news-mysql

# 检查脚本权限
ls -l docker/init-db/*.sql

解决: 确保SQL文件有读权限

问题2: SQL语法错误

症状: 容器启动失败

排查:

# 查看详细错误
docker logs school-news-mysql 2>&1 | grep ERROR

解决: 检查SQL语法在本地测试

问题3: 重复执行导致错误

症状: 主键冲突等错误

解决: 使用幂等设计

-- 使用INSERT IGNORE
INSERT IGNORE INTO ...

-- 使用ON DUPLICATE KEY UPDATE
INSERT INTO ... ON DUPLICATE KEY UPDATE ...

-- 检查执行状态
IF NOT EXISTS (SELECT ...)

📚 相关文档


更新时间: 2025-11-24
基于: schoolNewsServ/.bin/mysql/sql/reInit.sh