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

373 lines
8.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.

# 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