MySQL 常用命令速查手册:从建表到查询优化

zheng头像
zheng 2026-07-15 17:02
楼主

"SELECT 后面接什么来着?"、"加个外键怎么写?"、"怎么查某张表有没有某个字段?"——每次写 SQL 都要掏手机查,查着查着 5 分钟过去了。这份速查手册整理了 MySQL 最常用的命令,从建库建表到查询优化,需要的时候直接 Ctrl+F。


一、库操作

-- 创建数据库
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 查看所有数据库
SHOW DATABASES;

-- 切换数据库
USE mydb;

-- 查看当前所在数据库
SELECT DATABASE();

-- 删除数据库(慎用!)
DROP DATABASE mydb;

为什么用 utf8mb4 而不是 utf8?因为 MySQL 的 utf8 是个阉割版,最多 3 字节,存不了 emoji(😀)。utf8mb4 才是真正的 UTF-8。


二、表操作

-- 创建表
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL,
    age TINYINT UNSIGNED DEFAULT 0,
    status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_email (email),
    INDEX idx_status_created (status, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 查看当前库所有表
SHOW TABLES;

-- 查看表结构
DESC users;
SHOW CREATE TABLE users;  -- 完整建表语句

-- 查看表的所有索引
SHOW INDEX FROM users;

-- 修改表
ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email;
ALTER TABLE users MODIFY COLUMN age SMALLINT UNSIGNED;
ALTER TABLE users DROP COLUMN phone;
ALTER TABLE users RENAME TO customers;

-- 删除表(慎用!)
DROP TABLE users;


三、常用字段类型速查

类型 用途 示例
INT / BIGINT 整数 用户 ID、数量
TINYINT(1) 布尔值 is_deleted
DECIMAL(10,2) 精确金额 99999999.99
VARCHAR(N) 变长字符串 用户名、邮箱
TEXT 长文本 文章正文
LONGTEXT 超长文本 Markdown 全文
DATETIME 日期时间 2026-07-15 15:30:00
TIMESTAMP Unix 时间戳 自动记录的创建时间
ENUM 固定选项 状态字段
JSON JSON 数据 配置、扩展字段

选型口诀:钱用 DECIMAL,不长不短用 VARCHAR,要查的就加索引。


四、增删改(CRUD)

-- 插入
INSERT INTO users (username, email, age) VALUES ('john', '[email protected]', 25);
INSERT INTO users (username, email, age) VALUES
    ('alice', '[email protected]', 30),
    ('bob', '[email protected]', 28);

-- 查询
SELECT * FROM users;
SELECT id, username, email FROM users WHERE status = 'active';
SELECT * FROM users WHERE age BETWEEN 20 AND 30;
SELECT * FROM users WHERE email LIKE '%@gmail.com';
SELECT DISTINCT status FROM users;

-- 聚合查询
SELECT status, COUNT(*) AS cnt FROM users GROUP BY status;
SELECT status, COUNT(*) AS cnt FROM users GROUP BY status HAVING cnt > 5;

-- 排序和分页
SELECT * FROM users ORDER BY created_at DESC;
SELECT * FROM users LIMIT 10 OFFSET 20;    -- 第 3 页,每页 10 条

-- 更新
UPDATE users SET status = 'inactive' WHERE id = 1;
UPDATE users SET age = age + 1 WHERE status = 'active';    -- 活跃用户年龄 +1

-- 删除
DELETE FROM users WHERE id = 1;
DELETE FROM users WHERE created_at < '2025-01-01';    -- 删掉去年的旧数据

-- 软删除(推荐)
UPDATE users SET is_deleted = 1, deleted_at = NOW() WHERE id = 1;

生产环境不要用 DELETE 做硬删除,加个 is_deleted 字段做软删除,后悔药好买。


五、多表查询

-- 内连接(只返回两表都匹配的行)
SELECT u.username, o.order_no, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;

-- 左连接(返回左表全部 + 右表匹配的)
SELECT u.username, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id;

-- 子查询
SELECT * FROM users WHERE id IN (
    SELECT user_id FROM orders WHERE amount > 1000
);

-- 联合查询(两表结构一样时合并结果)
SELECT username, email FROM users
UNION ALL
SELECT username, email FROM archived_users;

UNIONUNION ALL 的区别:UNION 会去重(慢),UNION ALL 不去重(快)。确定不会重复就用 UNION ALL


六、索引优化(重点)

索引是数据库提速的第一手段,加对索引,查询从扫全表变成直接定位。

-- 创建索引
CREATE INDEX idx_username ON users(username);                        -- 普通索引
CREATE UNIQUE INDEX idx_email ON users(email);                       -- 唯一索引
CREATE INDEX idx_status_created ON users(status, created_at);        -- 联合索引

-- 查看查询是否用到索引
EXPLAIN SELECT * FROM users WHERE email = '[email protected]';

EXPLAIN 关键字段解读

字段
type const, eq_ref, ref, range ALL(全表扫描)
key 有值(命中索引) NULL(没用到索引)
rows 越小越好 几千几万就糟了
Extra Using index(覆盖索引) Using filesort, Using temporary

索引最佳实践

  • 最左前缀原则:联合索引 (A, B, C) 能匹配 WHERE AWHERE A AND B,但不能单独匹配 WHERE B
  • 不要在索引列上做计算WHERE YEAR(created_at) = 2026 不走索引,应改为 WHERE created_at BETWEEN '2026-01-01' AND '2026-12-31'
  • 区分度低的字段别单独建索引gender(男女)这种只有两三个值的字段建索引效率极低
  • 避免 SELECT *:只查需要的字段,配合覆盖索引效果更好


七、慢查询定位

-- 开启慢查询日志(临时)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;     -- 超过 1 秒就算慢查询

-- 查看慢查询日志位置
SHOW VARIABLES LIKE 'slow_query_log_file';

-- 查看当前正在执行的查询
SHOW FULL PROCESSLIST;

-- 杀掉某个卡死的查询
KILL 123;   -- 123 是 processlist 里的 Id

慢查询日志是找到性能瓶颈的最直接手段。建议线上环境 long_query_time 设 0.5 秒。


八、备份与恢复

-- 导出单个数据库
mysqldump -u root -p mydb > mydb_backup.sql

-- 导出所有数据库
mysqldump -u root -p --all-databases > all_backup.sql

-- 只导出表结构(不要数据)
mysqldump -u root -p --no-data mydb > schema.sql

-- 恢复
mysql -u root -p mydb < mydb_backup.sql

生产环境一定要定期自动备份,配合 cron 每天凌晨跑一次:

0 3 * * * mysqldump -u root -p'密码' mydb | gzip > /backup/mydb_$(date +\%Y\%m\%d).sql.gz


九、常用运维命令

-- 查看 MySQL 版本
SELECT VERSION();

-- 查看当前连接数
SHOW STATUS LIKE 'Threads_connected';

-- 查看数据库大小
SELECT table_schema AS '数据库',
       ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)'
FROM information_schema.tables
GROUP BY table_schema;

-- 查看某张表的大小
SELECT table_name,
       ROUND((data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)'
FROM information_schema.tables
WHERE table_schema = 'mydb' AND table_name = 'users';

-- 查看表行数(InnoDB 下是近似值)
SELECT TABLE_ROWS FROM information_schema.tables
WHERE table_schema = 'mydb' AND table_name = 'users';

-- 分析表(更新索引统计信息)
ANALYZE TABLE users;


十、防坑指南

后果 正确做法
DELETE 不加 WHERE 全表删除 SELECT 确认,再改写为 DELETE
UPDATE 不加 WHERE 全表更新 同上,跑之前必须有 WHERE
生产环境 DROP 表没了 永远不要对生产直接 DROP
utf8 而不是 utf8mb4 emoji 存不了 建库永远用 utf8mb4
字段无默认值 插入报错 养成给字段设 DEFAULT 的习惯
超大 OFFSET 翻页越翻越慢 用游标分页:WHERE id > 上一页最后一条id LIMIT 10


这份手册常用的东西都覆盖了,遇到没列出来的,mysql --help 或者 \h 进 MySQL 敲 help contents 也能查。把这些命令敲熟了,日常开发 95% 的 SQL 场景都够用了。

自建网站监控:Uptime Kuma 部署教程 Termux 入门指南:把 Android 手机变成随身 Linux 终端

最新回复

暂无回复,来说两句吧

发表评论

站点总访问量:2844