☰
👁️ 预览
取消
💾 保存
C
Claude
▾
C
Claude
claude@note.center
🔔
消息通知
🔄
账号切换
⚙️
设置
🚪
退出登录
Markdown
富文本
# MySQL 数据库运维学习笔记(Docker 实操 + Flask 迁移) > 日期:2026-07-06 > 学习方式:Docker 容器实操 + Note Center 从 SQLite 迁移到 MySQL --- ## 第一部分:Docker 基础 ### 什么是 Docker? Docker 是一个容器化平台,把软件连同它的运行环境打包成一个"镜像"(Image),一条命令就能启动。运行起来的镜像叫"容器"(Container)。 **类比:** 镜像 ≈ ISO 安装盘,容器 ≈ 装好系统的虚拟机。 ### 安装 Docker(OpenCloudOS 9.4) ```bash # 添加 Docker 官方源 dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装 Docker 引擎和命令行工具 dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 启动 Docker systemctl start docker # 验证 docker --version docker info ``` ### Docker 核心命令 ```bash docker pull 镜像名 # 下载镜像 docker run -d --name 容器名 镜像名 # 后台运行容器 docker ps -a # 查看所有容器 docker exec -i 容器名 命令 # 在容器内执行命令 docker images # 查看本地镜像列表 ``` ### 端口映射 `-p 宿主机端口:容器端口` — 把容器内的端口暴露到宿主机。 例如:`-p 3306:3306` 让宿主机能通过 `127.0.0.1:3306` 访问容器里的 MySQL。 --- ## 第二部分:MySQL 安装与部署(Docker) ```bash # 拉取 MySQL 8.0 镜像 docker pull mysql:8.0 # 启动 MySQL 容器 docker run -d \ --name mysql-demo \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=root123 \ mysql:8.0 ``` ### 参数说明 | 参数 | 含义 | |------|------| | `-d` | 后台运行 | | `--name mysql-demo` | 容器名字 | | `-p 3306:3306` | 端口映射 | | `-e MYSQL_ROOT_PASSWORD=root123` | 设置 root 密码 | ### 验证连接 ```bash # 查看容器状态 docker ps -a --filter name=mysql-demo(过滤条件) --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"(自定义输出格式。--format 用 Go 模板语法,table 开头表示带表头:\t 是制表符,用来对齐列) # 在容器内执行 MySQL 命令 docker exec -i mysql-demo mysql -uroot -proot123 -e "SHOW DATABASES;" ``` ### `docker exec` 全链路解析 ```bash docker exec -i mysql-demo mysql -uroot -proot123 -e "SHOW DATABASES;" ``` | 分段 | 作用 | |------|------| | `docker exec` | 钻进容器执行命令 | | `-i` | 保持交互 | | `mysql-demo` | 目标容器名 | | `mysql` | 容器里的 MySQL 客户端程序 | | `-uroot -proot123` | 用 root 登录,密码 root123 | | `-e "SQL语句"` | 执行一次 SQL 后就退出 | **整条命令的流程:** 宿主机 → Docker 引擎 → 容器 → mysql 客户端 → 连接到容器内的 mysqld → 执行 SQL → 返回结果。 #### 用户疑问:为什么不是用 `SELECT * FROM ops_db`? 因为 `SELECT` 后面只能跟**表名**,不能跟**数据库名**。数据库相当于文件夹,表才是文件。正确写法是 `SELECT * FROM ops_db.servers`(库名.表名)或先 `USE ops_db;` 再 `SELECT * FROM servers;`。 #### 用户疑问:输出结果只有列名没有内容? `SHOW DATABASES;` 的结果中,`information_schema`、`mysql`、`performance_schema`、`sys` 这些就是内容——它们是 MySQL 自带的系统数据库的名字。列名叫 `Database`,下面每一行都是一个数据库的实际名称。 #### 用户疑问:ops_db 是什么时候创建的? 在第三课实操中通过 `CREATE DATABASE IF NOT EXISTS ops_db` 创建的。它是一个练习用的"沙盒"数据库,后续的建表、插数据、权限管理、备份恢复都在里面操作。 --- ## 第三部分:MySQL 基础概念 ### MySQL 是什么? MySQL 是一个数据库管理软件(服务程序叫 mysqld),一直后台运行监听 3306 端口,接收 SQL 命令来读写数据。 ### 对比 SQLite vs MySQL | | SQLite | MySQL | |--|--------|-------| | 运行方式 | 嵌入在程序里,直接读写文件 | 独立服务程序 | | 如何连接 | 直接打开 .db 文件 | mysql -u用户 -p密码 -h地址 | | 用户权限 | 无 | 有 | | 多人同时用 | 不行(写锁) | 支持 | | 适用场景 | 开发环境、小工具 | 生产环境 | | 端口 | 无 | 3306 | ### 层级结构 ``` MySQL 服务器 └── 数据库(Database) ← 像 Excel 文件 └── 表(Table) ← 像 Excel 里的 Sheet ├── 列(Column)← 像 A/B/C 列(字段名) └── 行(Row) ← 一条数据记录 ``` ### 数据类型 | 类型 | 说明 | 示例 | |------|------|------| | INT | 整数 | cpu_cores INT | | VARCHAR(N) | 变长字符串,最长 N 字符 | hostname VARCHAR(64) | | DECIMAL(M,D) | 精确小数,M 总位 D 小数位 | memory_gb DECIMAL(5,2) | | ENUM('a','b') | 枚举,只能选列出的值 | status ENUM('running','stopped') | | DATETIME | 日期时间 | created_at DATETIME | ### 常用约束 | 约束 | 作用 | |------|------| | NOT NULL | 必填,不能为空 | | DEFAULT 值 | 没填时自动补这个值 | | PRIMARY KEY | 主键,唯一标识每一行 | | AUTO_INCREMENT | 自动递增 | | COMMENT '说明' | 字段注释 | ### CRUD 四大操作 ```sql -- 查 SELECT * FROM 库名.表名; SELECT 列1, 列2 FROM 表名 WHERE 条件; -- 增 INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2); -- 改(一定要写 WHERE!) UPDATE 表名 SET 列=新值 WHERE 条件; -- 删(一定要写 WHERE!) DELETE FROM 表名 WHERE 条件; ``` > **运维金句:** 没有 WHERE 的 UPDATE 和 DELETE 就是删库跑路。 --- ## 第四部分:用户权限管理 ### 为什么不能都用 root? 生产环境需要**最小权限原则**——每个用户只给够用的权限。 ### 用户由两部分组成 ```sql '用户名'@'主机' ``` | 写法 | 含义 | |------|------| | 'u'@'localhost' | 只能从本机连 | | 'u'@'%' | 任何地方都能连 | | 'u'@'192.168.1.%' | 只允许内网段 | ### 常用命令 ```sql CREATE USER '用户名'@'主机' IDENTIFIED BY '密码'; GRANT 权限 ON 库.表 TO '用户'@'主机'; SHOW GRANTS FOR '用户'@'主机'; ``` ### 实操:创建只读用户 ```sql CREATE USER 'dev_zhou'@'localhost' IDENTIFIED BY 'Monitor@2024'; GRANT SELECT ON ops_db.* TO 'monitor'@'localhost'; -- 验证:可以 SELECT,但 DELETE 被拒绝 加权限 GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'dev_zhou'@'localhost'; ``` --- ## 第五部分:mysqldump 备份与恢复 ### 备份 ```bash docker exec mysql-demo mysqldump -uroot -proot123 ops_db > backup.sql ``` ### 备份文件的内容 备份文件包含 `CREATE TABLE`(建表结构)+ `INSERT INTO`(插数据)的 SQL 命令。 ### 恢复 ```bash docker exec -i mysql-demo mysql -uroot -proot123 ops_db < backup.sql ``` ### 备份 vs 恢复对比 | | >(备份) | <(恢复) | |--|-------------|-------------| | 方向 | 数据库 → 文件 | 文件 → 数据库 | | 程序 | mysqldump | mysql 客户端 | --- ## 第六部分:慢查询排查与索引优化 ### 为什么 SQL 会慢? 根本原因是 MySQL 需要扫描太多数据才能找到你要的结果。 ### 索引是什么? 索引就像字典的拼音目录——排好序的数据结构,让 MySQL 能用二分查找快速定位,而不是逐行扫描全表。 ### EXPLAIN 只看三个指标 docker exec mysql-demo mysql -uroot -proot123 -e "USE ops_db; DESC test_slow; SHOW INDEX FROM test_slow;" 2>&1 | 指标 | 好的信号 | 坏的信号 | |------|---------|---------| | type | ref(索引查找) | ALL(全表扫描) | | rows | 个位数 | 几万以上行数 | | key | 有索引名 | NULL(没用索引) | ### 加索引 ```sql CREATE INDEX idx_name ON 表名 (列名); -- 只给经常出现在 WHERE 条件里的列加索引 EXPLAIN SELECT * FROM test_slow WHERE username = 'user_100'; ``` ### 慢查询日志 ```sql docker exec mysql-demo mysql -uroot -proot123 -e "SHOW VARIABLES LIKE 'slow_query_log_file'; SHOW VARIABLES LIKE 'slow_query_log'; SHOW VARIABLES LIKE 'long_query_time';" 2>&1 docker exec mysql-demo cat /var/lib/mysql/ff129f65a5fa-slow.log | tail -50(MySQL 跑在 Docker 容器里,宿主机 /var/lib/mysql 下没有文件) SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 2; ``` --- ## 第七部分:Flask + MySQL 迁移 ### 整体流程 ``` ① 在 MySQL 里创建 note_center 库和用户 nc_app ② pip install pymysql(Python 连 MySQL 的驱动) ③ 改 config.py(加 MySQL 连接配置) ④ 改 database.py(pymysql 替换 sqlite3,建表语句适配 MySQL 语法) ⑤ 改 models.py(? → %s,FTS5 → FULLTEXT,NULLS LAST 处理) ⑥ 改 monitor.py + routes.py + app.py ⑦ 启动测试 ``` ### 核心语法差异 | SQLite | MySQL | |--------|-------| | INTEGER PRIMARY KEY AUTOINCREMENT | INT AUTO_INCREMENT PRIMARY KEY | | REAL | DOUBLE | | TEXT NOT NULL DEFAULT '' | 不支持,改为 VARCHAR 或无 DEFAULT | | INSERT OR IGNORE | INSERT IGNORE | | ORDER BY col ASC NULLS LAST | ORDER BY (col IS NULL) ASC, col ASC | | ? 参数占位符 | %s 参数占位符 | ### 迁移前后 ``` 改之前:Note Center → SQLite 文件 (data/notes.db) 改之后:Note Center → MySQL 8.0 容器 (mysql-demo:3306) ``` ### 启动顺序(机器重启后) ```bash docker start mysql-demo # 先启动 MySQL python3 app.py # 再启动 Note Center ``` --- ## 学习收获总结 | 领域 | 掌握内容 | |------|---------| | Docker | 安装、镜像/容器概念、核心命令、端口映射 | | MySQL 基础 | 数据库结构、数据类型、约束、CRUD | | MySQL 权限 | 创建用户、授权、最小权限原则 | | MySQL 备份 | mysqldump 备份与恢复 | | 索引优化 | EXPLAIN 分析、CREATE INDEX、慢查询日志 | | 项目迁移 | SQLite → MySQL 全流程、语法差异处理 |
预览
编辑内容后实时预览...