MySQL-01 概述与快速上手
目录
MySQL 概述与快速上手
目录
1. MySQL 简介与版本演进
MySQL 是世界上最流行的开源关系型数据库,由瑞典 MySQL AB 公司开发,后被 Sun 收购,最终归入 Oracle 旗下。社区维护的分支 MariaDB 由 MySQL 创始人 Monty Widenius 主导,兼容性极强。
1.1 重要版本里程碑
| 版本 | 发布时间 | 关键特性 |
|---|---|---|
| 5.5 | 2010 | InnoDB 成为默认引擎,半同步复制 |
| 5.6 | 2013 | GTID 复制、在线 DDL、全文索引优化 |
| 5.7 | 2015 | JSON 类型、原生 JSON 函数、组复制(MGR 预研)、多源复制 |
| 8.0 | 2018 | 窗口函数、CTE(WITH)、Hash Join、降序索引、原子 DDL、角色管理、utf8mb4 默认 |
| 8.4 | 2024 | LTS 长期支持版,简化复制配置 |
生产建议:新项目首选 MySQL 8.0/8.4,5.7 已于 2023 年 10 月停止维护。
1.2 MySQL vs MariaDB vs Percona
MySQL (Oracle) ──── 社区版(免费)/ 企业版(商业)
MariaDB ──── MySQL 分叉,开源更彻底,部分功能超前
Percona Server ──── 针对高性能优化,工具链最丰富(pt-query-digest 等)
2. MySQL 核心特性一览
2.1 存储引擎插件化
MySQL 最独特的设计——存储引擎可插拔,上层 SQL 层与底层存储完全解耦:
SQL 层(解析、优化、执行)
│
┌────┴────┐
InnoDB MyISAM Memory CSV Archive ...
- InnoDB:默认引擎,支持事务、行锁、MVCC、外键
- MyISAM:不支持事务,表锁,适合读多写少场景(基本淘汰)
- Memory:数据存内存,重启丢失,适合临时表
- CSV:以 CSV 格式存储,方便数据交换
2.2 ACID 事务
InnoDB 完整实现 ACID,依赖:
- Undo Log:原子性(A)+ 隔离性(I)的 MVCC
- Redo Log:持久性(D)
- 锁机制:隔离性(I)
2.3 SQL 标准兼容
MySQL 兼容 SQL-92 大部分标准,8.0 起对 SQL 标准兼容度进一步提升(窗口函数、CTE 等)。
3. Docker 快速部署
3.1 单机部署
# MySQL 8.0
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=root123 \
-e MYSQL_DATABASE=devdb \
-v $(pwd)/mysql/data:/var/lib/mysql \
-v $(pwd)/mysql/conf:/etc/mysql/conf.d \
--restart unless-stopped \
mysql:8.0
# 查看日志
docker logs -f mysql8
3.2 自定义配置文件
# $(pwd)/mysql/conf/my.cnf
[mysqld]
# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 时区
default-time-zone = '+8:00'
# 慢查询
slow_query_log = ON
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 1
# binlog
log_bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
# InnoDB Buffer Pool(建议设为可用内存的 60-80%)
innodb_buffer_pool_size = 256M
3.3 docker-compose 方式
# docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql8
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: devdb
MYSQL_USER: dev
MYSQL_PASSWORD: dev123
volumes:
- mysql_data:/var/lib/mysql
- ./conf/my.cnf:/etc/mysql/conf.d/my.cnf
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mysql_data:
docker-compose up -d
docker-compose exec mysql mysql -uroot -proot123
4. 常用客户端工具
4.1 命令行客户端
# 连接
mysql -h 127.0.0.1 -P 3306 -u root -p
# 直接执行 SQL
mysql -u root -p devdb -e "SELECT VERSION();"
# 导入 SQL 文件
mysql -u root -p devdb < dump.sql
# 常用 meta 命令
\s # 查看连接状态
\G # 结果竖排显示
\c # 取消当前语句
\q # 退出
source /tmp/init.sql # 执行文件
4.2 mysqladmin
mysqladmin -u root -p status # 服务器状态
mysqladmin -u root -p processlist # 当前连接
mysqladmin -u root -p variables # 查看变量
mysqladmin -u root -p flush-logs # 刷新日志
mysqladmin -u root -p shutdown # 关闭服务器
4.3 mysqldump / mysqlpump
# 备份单个数据库
mysqldump -u root -p --single-transaction devdb > devdb.sql
# 备份所有数据库
mysqldump -u root -p --all-databases --single-transaction > all.sql
# 恢复
mysql -u root -p devdb < devdb.sql
4.4 GUI 工具推荐
| 工具 | 平台 | 特点 |
|---|---|---|
| TablePlus | macOS/Win | 轻量快速,UI 好看 |
| DataGrip | 全平台 | JetBrains 出品,功能最强 |
| DBeaver | 全平台 | 开源免费,支持众多数据库 |
| Navicat | 全平台 | 老牌工具,功能全 |
| MySQL Workbench | 全平台 | 官方工具,ER 图设计强 |
5. 数据库基本操作
5.1 数据库管理
-- 查看所有数据库
SHOW DATABASES;
-- 创建数据库
CREATE DATABASE IF NOT EXISTS myapp
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 切换数据库
USE myapp;
-- 查看当前数据库
SELECT DATABASE();
-- 删除数据库(谨慎!)
DROP DATABASE IF EXISTS myapp;
5.2 用户与权限
-- 创建用户
CREATE USER 'app'@'%' IDENTIFIED BY 'AppPass123!';
-- 授权(推荐最小权限原则)
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'app'@'%';
-- 查看权限
SHOW GRANTS FOR 'app'@'%';
-- 撤销权限
REVOKE DELETE ON myapp.* FROM 'app'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
-- 修改密码(MySQL 8.0)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass123!';
-- 删除用户
DROP USER 'app'@'%';
5.3 查看服务器状态
-- MySQL 版本
SELECT VERSION();
-- 当前时间
SELECT NOW(), SYSDATE(), CURRENT_TIMESTAMP;
-- 查看系统变量
SHOW VARIABLES LIKE 'innodb_buffer%';
SHOW VARIABLES LIKE '%timeout%';
-- 查看状态变量
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Innodb_buffer_pool%';
-- 当前连接
SHOW PROCESSLIST;
-- 或更详细
SELECT * FROM information_schema.PROCESSLIST;
-- 查看表状态
SHOW TABLE STATUS FROM myapp LIKE 'orders'\G
6. 字符集与排序规则
MySQL 8.0 之前默认字符集是 latin1,生产环境必须显式设置 utf8mb4。
6.1 为什么是 utf8mb4
MySQL 的 utf8 实际上是 utf8mb3,最多 3 个字节,无法存储 emoji(需要 4 字节)。utf8mb4 才是真正的 UTF-8。
-- 查看字符集
SHOW CHARACTER SET LIKE 'utf8%';
-- 查看排序规则
SHOW COLLATION WHERE Charset = 'utf8mb4';
6.2 常用 utf8mb4 排序规则
| 排序规则 | 说明 |
|---|---|
utf8mb4_general_ci |
不区分大小写,速度快,比较不够精确 |
utf8mb4_unicode_ci |
不区分大小写,基于 Unicode 标准,更准确 |
utf8mb4_0900_ai_ci |
MySQL 8.0 新默认,Unicode 9.0,ai=accent insensitive |
utf8mb4_bin |
区分大小写,按字节比较,最严格 |
推荐:中文场景用
utf8mb4_unicode_ci,需要区分大小写用utf8mb4_bin。
6.3 修改字符集
-- 修改数据库
ALTER DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改表
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改列
ALTER TABLE users MODIFY name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
7. 数据类型速查
7.1 数值类型
| 类型 | 字节 | 范围(有符号) | 说明 |
|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 布尔值常用 |
| SMALLINT | 2 | -32768 ~ 32767 | |
| MEDIUMINT | 3 | -8388608 ~ 8388607 | |
| INT | 4 | -2147483648 ~ 2147483647 | 最常用 |
| BIGINT | 8 | ±9.2×10¹⁸ | 分布式 ID 常用 |
| FLOAT | 4 | 近似值 | 不精确,慎用于金额 |
| DOUBLE | 8 | 近似值 | 不精确 |
| DECIMAL(M,D) | 变长 | 精确值 | 金额必用 |
Go 注意:DECIMAL 在 Go 中用
string接收可以避免精度丢失,或使用shopspring/decimal库。
7.2 字符串类型
| 类型 | 最大长度 | 说明 |
|---|---|---|
| CHAR(N) | 255 字符 | 定长,右填充空格,适合固定长度(手机号、状态码) |
| VARCHAR(N) | 65535 字节 | 变长,有 1-2 字节长度前缀 |
| TINYTEXT | 255 字节 | |
| TEXT | 65535 字节 | 不能有默认值,不能建索引(前缀索引可以) |
| MEDIUMTEXT | 16MB | |
| LONGTEXT | 4GB | |
| TINYBLOB/BLOB/… | 同上 | 二进制 |
| JSON | 4GB | MySQL 5.7+,原生 JSON 类型 |
7.3 时间类型
| 类型 | 字节 | 范围 | 说明 |
|---|---|---|---|
| DATE | 3 | 1000-01-01 ~ 9999-12-31 | 仅日期 |
| TIME | 3 | -838:59:59 ~ 838:59:59 | 仅时间 |
| DATETIME | 8 | 1000-01-01 ~ 9999-12-31 | 日期+时间,不受时区影响 |
| TIMESTAMP | 4 | 1970-01-01 ~ 2038-01-19 | 存 Unix 时间戳,受时区影响 |
| YEAR | 1 | 1901 ~ 2155 |
踩坑:TIMESTAMP 会自动根据
time_zone变量转换,跨时区部署时注意;2038 年问题用 DATETIME 可规避。
-- 创建时自动维护时间戳
CREATE TABLE orders (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT UNSIGNED NOT NULL,
amount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
status TINYINT NOT NULL DEFAULT 0 COMMENT '0:待付款 1:已付款 2:已发货',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
8. Go 连接 MySQL 初体验
8.1 安装驱动
go get github.com/go-sql-driver/mysql
go get github.com/jmoiron/sqlx # 增强版 database/sql
8.2 标准库连接
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// DSN: user:password@tcp(host:port)/dbname?params
dsn := "root:root123@tcp(127.0.0.1:3306)/devdb" +
"?charset=utf8mb4" +
"&parseTime=True" + // 自动解析 time.Time
"&loc=Local" + // 使用本地时区
"&timeout=5s" + // 连接超时
"&readTimeout=10s" + // 读超时
"&writeTimeout=5s" // 写超时
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 连接池配置(重要!)
db.SetMaxOpenConns(100) // 最大连接数
db.SetMaxIdleConns(10) // 最大空闲连接数
db.SetConnMaxLifetime(time.Hour) // 连接最大生命周期
db.SetConnMaxIdleTime(30 * time.Minute) // 空闲连接最大存活时间
// 测试连通性
if err = db.Ping(); err != nil {
log.Fatal("ping failed:", err)
}
fmt.Println("MySQL connected!")
// 查询示例
var version string
err = db.QueryRow("SELECT VERSION()").Scan(&version)
if err != nil {
log.Fatal(err)
}
fmt.Println("MySQL version:", version)
}
8.3 DSN 常用参数
| 参数 | 说明 | 默认值 |
|---|---|---|
charset |
字符集 | 服务器默认 |
parseTime |
自动解析为 time.Time | false |
loc |
时区 | UTC |
timeout |
连接超时 | 无 |
readTimeout |
读超时 | 无 |
writeTimeout |
写超时 | 无 |
tls |
TLS 配置 | false |
interpolateParams |
客户端参数插值(慎用,有 SQL 注入风险) | false |
multiStatements |
允许多语句 | false |
collation |
排序规则 | utf8mb4_general_ci |
小结
- MySQL 生产推荐 8.0+,新项目别用 5.7
- 字符集统一用
utf8mb4,排序规则用utf8mb4_unicode_ci - Docker 部署方便,记得挂载数据目录和配置文件
- 金额用
DECIMAL,时间戳跨时区用DATETIME - Go 连接时
parseTime=True和合理的连接池配置缺一不可
xingliuhua