以下是 MySQL 中最重要的增删改查(CRUD)操作,附带常用写法和注意事项。
1. 增(INSERT)
单行插入:
sql
INSERT INTO users (name, email, age)
VALUES ('张三', 'zhangsan@example.com', 28);
批量插入:
sql
INSERT INTO users (name, email, age) VALUES
('李四', 'lisi@example.com', 32),
('王五', 'wangwu@example.com', 25);
从其他表查询并插入:
sql
INSERT INTO vip_users (name, email)
SELECT name, email FROM users WHERE age > 30;
忽略重复或更新:
主键/唯一键冲突时忽略:
sql
INSERT IGNORE INTO users (id, name) VALUES (1, '张三');
冲突时更新其他字段:
sql
INSERT INTO users (id, name, email) VALUES (1, '张三', 'new@example.com')
ON DUPLICATE KEY UPDATE name='张三', email='new@example.com';
2. 删(DELETE)
根据条件删除(必须加 WHERE,否则清空整表):
sql
DELETE FROM users WHERE id = 10;
删除全表数据(保留表结构):
sql
DELETE FROM users; -- 逐行删除,可回滚,会触发触发器,不重置自增ID
TRUNCATE TABLE users; -- 直接删除表并重建,更快,无法回滚,重置自增ID
多表删除(根据关联条件删除):
sql
DELETE u FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.status = 'cancelled';
3. 改(UPDATE)
更新单列:
sql
UPDATE users SET age = 29 WHERE id = 5;
更新多列:
sql
UPDATE users SET email = 'new@example.com', age = 30 WHERE name = '张三';
根据其他表更新:
sql
UPDATE users u
JOIN orders o ON u.id = o.user_id
SET u.vip_level = 'gold'
WHERE o.total_amount > 10000;
错误提醒:
忘记 WHERE 会更新全表!安全做法是先用相同条件的 SELECT 确定行数,或开启事务后再执行。
4. 查(SELECT)
基本查询:
sql
SELECT id, name, email FROM users;
SELECT * FROM users; -- 生产环境避免 * ,只取需要的列
条件过滤(WHERE):
sql
SELECT * FROM users WHERE age > 18 AND status = 'active';
SELECT * FROM users WHERE name LIKE '张%'; -- 模糊一致
SELECT * FROM users WHERE id IN (1,3,5);
SELECT * FROM users WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';
排序和分页:
sql
SELECT * FROM users ORDER BY age DESC, name ASC; -- 多字段排序
SELECT * FROM users LIMIT 10 OFFSET 20; -- 跳过20行,取10行(第3页)
聚合函数和分组:
sql
SELECT city, COUNT(*) AS cnt, AVG(age) AS avg_age
FROM users
GROUP BY city
HAVING cnt > 5; -- 对分组结果过滤,不能用 WHERE
多表连接(JOIN):
sql
-- 内连接:两表都一致的数据
SELECT u.name, o.order_no
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
-- 左连接:左表全部数据,右表无一致则显示 NULL
SELECT u.name, o.order_no
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
子查询:
sql
SELECT * FROM users WHERE age > (SELECT AVG(age) FROM users);
SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE vip = 1);
5. 安全和性能重点
执行删除/更新前,先用 SELECT 确定影响范围:把 DELETE/UPDATE 的 WHERE 条件套入 SELECT count(*) 看看有多少行。
事务保护误操作:
sql
START TRANSACTION;
UPDATE users SET age = age + 1 WHERE status = 'active';
-- 检查是不是正确
COMMIT; -- 或 ROLLBACK 回滚
索引是查询加速的重点:对 WHERE、JOIN、ORDER BY 中的列建立索引。
防止 SQL 注入:在应用代码中始终使用参数化查询(预编译语句),不要拼接字符串。
避免SELECT :只查询需要的列,减少网络和内存开销。
大量数据分批处理:删除或更新大表时,用 LIMIT 分批执行,避免锁表过久。