# 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: 使用自动脚本(推荐) ```bash 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: 准备表结构 ```bash 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: 准备初始数据 ```bash # 合并所有init*.sql cat initMenuData.sql \ initAllData.sql \ initCrontabMetaData.sql \ > ../../docker/init-db/03-init-data.sql ``` #### 步骤3: 添加Docker配置 在 `03-init-data.sql` 末尾添加: ```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`: ```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` 语句: ```sql -- ❌ 不支持 SOURCE createTableUser.sql; -- ✅ 需要合并成一个文件 -- 将所有SQL内容直接写入 CREATE TABLE tb_user (...); CREATE TABLE tb_role (...); ``` ### 2. 幂等性设计 确保脚本可以重复执行: ```sql -- 使用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: ```sql CREATE TABLE tb_xxx ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` ## 🧪 测试验证 ### 1. 检查SQL文件 ```bash # 查看文件大小 ls -lh docker/init-db/*.sql # 检查SQL语法 cd docker/init-db mysql --help | grep "Default options" ``` ### 2. 本地测试 ```bash # 在本地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环境测试 ```bash # 删除旧数据 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. 验证初始化状态 ```bash # 查看初始化记录 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. 脚本会自动执行(按字母顺序) 示例迁移脚本: ```sql -- 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: 初始化脚本未执行 **症状**: 数据库创建了但表不存在 **排查**: ```bash # 查看MySQL日志 docker logs school-news-mysql # 检查脚本权限 ls -l docker/init-db/*.sql ``` **解决**: 确保SQL文件有读权限 ### 问题2: SQL语法错误 **症状**: 容器启动失败 **排查**: ```bash # 查看详细错误 docker logs school-news-mysql 2>&1 | grep ERROR ``` **解决**: 检查SQL语法,在本地测试 ### 问题3: 重复执行导致错误 **症状**: 主键冲突等错误 **解决**: 使用幂等设计 ```sql -- 使用INSERT IGNORE INSERT IGNORE INTO ... -- 使用ON DUPLICATE KEY UPDATE INSERT INTO ... ON DUPLICATE KEY UPDATE ... -- 检查执行状态 IF NOT EXISTS (SELECT ...) ``` ## 📚 相关文档 - [数据库初始化README](README.md) - [reInit.sh源文件](../../schoolNewsServ/.bin/mysql/sql/reInit.sh) - [MySQL Docker文档](https://hub.docker.com/_/mysql) --- **更新时间**: 2025-11-24 **基于**: schoolNewsServ/.bin/mysql/sql/reInit.sh