8.4 KiB
8.4 KiB
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
脚本会自动:
- 备份现有SQL文件
- 合并所有createTable*.sql到02-create-tables.sql
- 合并所有init*.sql到03-init-data.sql
- 添加Docker特定配置(爬虫路径等)
- 生成统计信息
方式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: 本地开发添加了新表
- 在
schoolNewsServ/.bin/mysql/sql/中创建SQL文件 - 更新
initAll.sql添加SOURCE语句 - 重新运行
prepare-sql.sh - 重新构建Docker镜像
场景2: 修改现有表结构
- 创建迁移脚本
04-migration-xxx.sql - 放入
docker/init-db/目录 - 脚本会自动执行(按字母顺序)
示例迁移脚本:
-- 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