作为关系型数据库的代表,MySQL凭借其稳定性和易用性成为开发者首选的数据库解决方案。今天我将结合多年实战经验,带大家系统掌握MySQL的核心操作技巧。
创建数据库是MySQL操作的起点,看似简单却暗藏玄机:
sql复制-- 基础创建语句
CREATE DATABASE db_name;
-- 安全创建方式(推荐)
CREATE DATABASE IF NOT EXISTS db_name
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
关键细节说明:
IF NOT EXISTS能避免重复创建导致的报错中断批量脚本执行- 字符集强烈建议使用utf8mb4而非utf8,完整支持emoji和生僻字
- 生产环境务必指定COLLATE(排序规则),避免跨服务器迁移时出现排序不一致
字符集选择经验谈:
查看数据库列表的正确姿势:
sql复制SHOW DATABASES;
/* 典型输出:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| your_db |
+--------------------+
*/
删除操作堪称DBA的噩梦,务必慎之又慎:
sql复制-- 危险操作!直接删除无确认
DROP DATABASE db_name;
-- 安全删除方案
DROP DATABASE IF EXISTS db_name;
血泪教训:某次误删生产库就是因为忘记加IF EXISTS判断,导致自动化脚本中断。建议:
- 删除前先备份(mysqldump)
- 使用权限分离,开发账号禁止DROP权限
- 启用binlog保证可回滚
创建表是数据库设计的核心,需要综合考虑业务需求和性能:
sql复制CREATE TABLE `user` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '用户名',
`balance` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '账户余额',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`),
KEY `idx_created` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
字段类型选择经验:
查看表结构的专业方法:
sql复制-- 基础查看
DESC user;
-- 详细信息(推荐)
SHOW CREATE TABLE user;
-- 查看表大小(MB单位)
SELECT
table_name AS `表名`,
round(data_length/1024/1024, 2) `数据大小(MB)`,
round(index_length/1024/1024, 2) `索引大小(MB)`
FROM information_schema.TABLES
WHERE table_schema = 'your_db';
删除表的避险方案:
sql复制-- 先确认数据已备份
CREATE TABLE user_bak LIKE user;
INSERT user_bak SELECT * FROM user;
-- 再执行删除
DROP TABLE IF EXISTS user;
基础插入:
sql复制INSERT INTO user VALUES(1, '张三', 100.00, NOW(), NOW());
推荐写法:
sql复制-- 指定列插入(更安全)
INSERT INTO user(username, balance)
VALUES('李四', 200.00);
-- 批量插入(性能提升5-10倍)
INSERT INTO user(username, balance) VALUES
('王五', 300.00),
('赵六', 400.00),
('钱七', 500.00);
日期处理技巧:
sql复制-- 使用函数
INSERT INTO orders(create_time) VALUES(NOW());
-- 指定格式字符串
INSERT INTO events(event_time) VALUES('2024-03-20 14:30:00');
-- 时间戳转换
INSERT INTO logs(log_time) VALUES(FROM_UNIXTIME(1710928800));
sql复制-- 全列查询(生产环境慎用)
SELECT * FROM user;
-- 指定列查询(推荐)
SELECT id, username FROM user;
sql复制-- 别名使用
SELECT
username AS '姓名',
balance*0.9 AS '税后金额'
FROM user;
-- 去重查询
SELECT DISTINCT department FROM employees;
-- 分页优化
SELECT * FROM large_table
ORDER BY id
LIMIT 10000, 10; -- 低效
SELECT * FROM large_table
WHERE id > 10000
ORDER BY id
LIMIT 10; -- 高效
sql复制-- 范围查询
SELECT * FROM products
WHERE price BETWEEN 50 AND 100;
-- 模糊查询
SELECT * FROM articles
WHERE title LIKE '%MySQL%';
-- NULL处理
SELECT * FROM customers
WHERE phone IS NOT NULL;
-- 组合条件
SELECT * FROM orders
WHERE status = 'paid'
AND amount > 1000
OR vip_flag = 1;
基础更新:
sql复制UPDATE user SET balance = 200 WHERE id = 1;
安全更新方案:
sql复制-- 先查询再更新
SELECT * FROM user WHERE username = '张三' FOR UPDATE;
UPDATE user SET balance = 300 WHERE username = '张三';
-- 限制更新范围
UPDATE products SET stock = stock - 1
WHERE id = 100 AND stock > 0
LIMIT 1;
-- 联表更新
UPDATE orders o
JOIN users u ON o.user_id = u.id
SET o.status = 'shipped'
WHERE u.vip_level > 3;
sql复制-- 危险操作!
DELETE FROM log_data;
-- 安全删除方案
-- 方案1:条件删除
DELETE FROM temp_data
WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 方案2:分批删除
DELETE FROM large_table
WHERE id < 10000
LIMIT 1000;
-- 方案3:重建表(大数据量时更快)
CREATE TABLE new_table LIKE old_table;
DROP TABLE old_table;
RENAME TABLE new_table TO old_table;
sql复制-- 添加索引
ALTER TABLE user ADD INDEX idx_email (email);
-- 联合索引优化
ALTER TABLE orders ADD INDEX idx_status_created (status, created_at);
-- 索引使用检查
EXPLAIN SELECT * FROM user WHERE username = 'test';
索引使用经验:
- 遵循最左前缀原则
- 区分度高的列适合建索引
- 避免在索引列上使用函数
- 定期使用ANALYZE TABLE更新统计信息
sql复制-- 典型事务示例
START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE user_id = 1;
UPDATE account SET balance = balance + 100 WHERE user_id = 2;
COMMIT;
-- 异常处理
BEGIN;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SELECT 'Transaction failed' AS result;
END;
-- 业务逻辑
COMMIT;
bash复制# 逻辑备份
mysqldump -u root -p --single-transaction --routines your_db > backup.sql
# 物理备份(Percona XtraBackup)
innobackupex --user=root --password=xxx /backup_path/
# 恢复测试
mysql -u root -p test_db < backup.sql
sql复制-- 查看连接数
SHOW STATUS LIKE 'Threads_connected';
-- 杀死异常连接
SELECT CONCAT('KILL ',id,';')
FROM information_schema.processlist
WHERE TIME > 300;
sql复制-- 查看慢查询
SELECT * FROM mysql.slow_log
ORDER BY start_time DESC
LIMIT 10;
-- 锁等待分析
SELECT * FROM performance_schema.events_waits_current
WHERE EVENT_NAME LIKE '%lock%';
sql复制-- 检查表状态
CHECK TABLE important_data FAST QUICK;
-- 修复表
REPAIR TABLE corrupted_table;
经过多年实战,我总结出MySQL操作的三个黄金原则:备份重于一切、变更必须测试、性能需要监控。特别是在执行DELETE/UPDATE这类写操作时,一定要先SELECT确认影响范围,或者先在测试环境验证。