[数据库] MySQL使用方法完整指南

577 0
Honkers 2026-1-18 05:35:12 来自手机 | 显示全部楼层 |阅读模式

一、MySQL 核心概念与架构

1.1 MySQL 体系结构

  1. 客户端层
  2. 连接层(连接池、线程池)
  3. SQL层(解析器、优化器、缓存)
  4. 存储引擎层(InnoDB、MyISAM、Memory)
  5. 物理存储层
复制代码

1.2 存储引擎对比

特性InnoDBMyISAMMemoryArchive
事务支持×××
行级锁×××
外键约束×××
全文索引✓ (5.6+)××
数据压缩×
缓存数据+索引仅索引内存
适用场景事务处理读密集型临时表归档

二、数据库基本操作

2.1 数据库管理

  1. -- 查看所有数据库
  2. SHOW DATABASES;
  3. -- 查看数据库创建语句
  4. SHOW CREATE DATABASE database_name;
  5. -- 创建数据库(指定字符集)
  6. CREATE DATABASE mydb
  7. CHARACTER SET utf8mb4
  8. COLLATE utf8mb4_unicode_ci;
  9. -- 选择数据库
  10. USE mydb;
  11. -- 修改数据库字符集
  12. ALTER DATABASE mydb
  13. CHARACTER SET utf8mb4
  14. COLLATE utf8mb4_unicode_ci;
  15. -- 删除数据库
  16. DROP DATABASE mydb;
复制代码

2.2 表管理

  1. -- 创建表(完整示例)
  2. CREATE TABLE employees (
  3. id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  4. emp_no VARCHAR(20) NOT NULL UNIQUE,
  5. name VARCHAR(100) NOT NULL,
  6. gender ENUM('M', 'F') DEFAULT 'M',
  7. birth_date DATE NOT NULL,
  8. hire_date DATE NOT NULL,
  9. salary DECIMAL(10,2) DEFAULT 0.00,
  10. department_id INT UNSIGNED,
  11. email VARCHAR(100) UNIQUE,
  12. phone VARCHAR(20),
  13. address TEXT,
  14. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  15. updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  16. ON UPDATE CURRENT_TIMESTAMP,
  17. -- 索引
  18. INDEX idx_department (department_id),
  19. INDEX idx_name (name),
  20. INDEX idx_hire_date (hire_date),
  21. -- 外键约束
  22. CONSTRAINT fk_department
  23. FOREIGN KEY (department_id)
  24. REFERENCES departments(id)
  25. ON DELETE SET NULL ON UPDATE CASCADE,
  26. -- 检查约束(MySQL 8.0.16+)
  27. CONSTRAINT chk_salary CHECK (salary >= 0)
  28. ) ENGINE=InnoDB
  29. DEFAULT CHARSET=utf8mb4
  30. COLLATE=utf8mb4_unicode_ci
  31. COMMENT='员工信息表';
  32. -- 查看表结构
  33. DESC employees;
  34. DESCRIBE employees;
  35. SHOW COLUMNS FROM employees;
  36. -- 查看建表语句
  37. SHOW CREATE TABLE employees;
  38. -- 修改表结构
  39. -- 添加列
  40. ALTER TABLE employees
  41. ADD COLUMN nickname VARCHAR(50) AFTER name;
  42. -- 修改列
  43. ALTER TABLE employees
  44. MODIFY COLUMN phone VARCHAR(30) NOT NULL;
  45. -- 重命名列
  46. ALTER TABLE employees
  47. CHANGE COLUMN phone mobile_phone VARCHAR(30);
  48. -- 删除列
  49. ALTER TABLE employees
  50. DROP COLUMN nickname;
  51. -- 添加索引
  52. ALTER TABLE employees
  53. ADD INDEX idx_email (email(50));
  54. -- 添加唯一索引
  55. ALTER TABLE employees
  56. ADD UNIQUE INDEX uk_emp_no (emp_no);
  57. -- 删除索引
  58. ALTER TABLE employees
  59. DROP INDEX idx_email;
  60. -- 重命名表
  61. RENAME TABLE employees TO staff;
  62. ALTER TABLE staff RENAME TO employees;
  63. -- 清空表(更快)
  64. TRUNCATE TABLE employees;
  65. -- 删除表
  66. DROP TABLE employees;
复制代码

三、数据操作(CRUD)

3.1 插入数据

  1. -- 插入单条数据
  2. INSERT INTO employees (emp_no, name, gender, birth_date, hire_date, salary)
  3. VALUES ('EMP001', '张三', 'M', '1990-05-15', '2020-03-01', 15000.00);
  4. -- 插入多条数据
  5. INSERT INTO employees (emp_no, name, gender, birth_date, hire_date, salary) VALUES
  6. ('EMP002', '李四', 'F', '1992-08-20', '2019-07-15', 18000.00),
  7. ('EMP003', '王五', 'M', '1988-12-10', '2018-11-01', 22000.00),
  8. ('EMP004', '赵六', 'F', '1995-03-25', '2021-02-14', 12000.00);
  9. -- 插入查询结果
  10. INSERT INTO employee_archive (emp_no, name, hire_date, salary)
  11. SELECT emp_no, name, hire_date, salary
  12. FROM employees
  13. WHERE hire_date < '2020-01-01';
  14. -- 替换数据(存在则替换)
  15. REPLACE INTO employees (id, emp_no, name)
  16. VALUES (1, 'EMP001', '张三新名字');
  17. -- 插入时忽略错误
  18. INSERT IGNORE INTO employees (emp_no, name)
  19. VALUES ('EMP001', '张三');
  20. -- 从文件导入数据
  21. LOAD DATA INFILE '/path/to/data.csv'
  22. INTO TABLE employees
  23. FIELDS TERMINATED BY ','
  24. ENCLOSED BY '"'
  25. LINES TERMINATED BY '\n'
  26. IGNORE 1 ROWS
  27. (emp_no, name, gender, birth_date, hire_date, salary);
复制代码

3.2 查询数据

  1. -- 基本查询
  2. SELECT * FROM employees;
  3. SELECT id, name, salary FROM employees;
  4. SELECT DISTINCT department_id FROM employees;
  5. -- 条件查询
  6. SELECT * FROM employees WHERE salary > 15000;
  7. SELECT * FROM employees WHERE hire_date BETWEEN '2020-01-01' AND '2021-12-31';
  8. SELECT * FROM employees WHERE name LIKE '张%'; -- 张开头
  9. SELECT * FROM employees WHERE name LIKE '%三%'; -- 包含三
  10. SELECT * FROM employees WHERE name LIKE '%三'; -- 三结尾
  11. SELECT * FROM employees WHERE email IS NOT NULL;
  12. SELECT * FROM employees WHERE department_id IN (1, 2, 3);
  13. SELECT * FROM employees WHERE (salary > 10000 AND gender = 'M') OR department_id = 1;
  14. -- 排序
  15. SELECT * FROM employees ORDER BY salary DESC;
  16. SELECT * FROM employees ORDER BY hire_date ASC, salary DESC;
  17. -- 限制结果
  18. SELECT * FROM employees LIMIT 10; -- 前10条
  19. SELECT * FROM employees LIMIT 5, 10; -- 从第6条开始,取10条
  20. SELECT * FROM employees LIMIT 10 OFFSET 5; -- 同上
  21. -- 分组统计
  22. SELECT
  23. department_id,
  24. COUNT(*) AS emp_count,
  25. AVG(salary) AS avg_salary,
  26. MAX(salary) AS max_salary,
  27. MIN(salary) AS min_salary,
  28. SUM(salary) AS total_salary
  29. FROM employees
  30. WHERE hire_date >= '2020-01-01'
  31. GROUP BY department_id
  32. HAVING COUNT(*) > 5
  33. ORDER BY avg_salary DESC;
  34. -- 连接查询
  35. -- 内连接
  36. SELECT
  37. e.name AS employee_name,
  38. d.name AS department_name,
  39. e.salary
  40. FROM employees e
  41. INNER JOIN departments d ON e.department_id = d.id
  42. WHERE d.name = '技术部';
  43. -- 左连接
  44. SELECT
  45. e.name AS employee_name,
  46. d.name AS department_name
  47. FROM employees e
  48. LEFT JOIN departments d ON e.department_id = d.id;
  49. -- 右连接
  50. SELECT
  51. e.name AS employee_name,
  52. d.name AS department_name
  53. FROM employees e
  54. RIGHT JOIN departments d ON e.department_id = d.id;
  55. -- 自连接
  56. SELECT
  57. e1.name AS employee,
  58. e2.name AS manager
  59. FROM employees e1
  60. LEFT JOIN employees e2 ON e1.manager_id = e2.id;
  61. -- 子查询
  62. -- WHERE 子查询
  63. SELECT * FROM employees
  64. WHERE salary > (SELECT AVG(salary) FROM employees);
  65. -- FROM 子查询
  66. SELECT dept_id, avg_sal FROM (
  67. SELECT department_id AS dept_id, AVG(salary) AS avg_sal
  68. FROM employees
  69. GROUP BY department_id
  70. ) AS temp
  71. WHERE avg_sal > 15000;
  72. -- SELECT 子查询
  73. SELECT
  74. e.name,
  75. e.salary,
  76. (SELECT AVG(salary) FROM employees) AS company_avg_salary
  77. FROM employees e;
  78. -- EXISTS 子查询
  79. SELECT * FROM departments d
  80. WHERE EXISTS (
  81. SELECT 1 FROM employees e
  82. WHERE e.department_id = d.id AND e.salary > 20000
  83. );
  84. -- 联合查询
  85. SELECT name, salary, '员工' AS type FROM employees
  86. UNION
  87. SELECT dept_name, budget, '部门' AS type FROM departments
  88. ORDER BY salary DESC;
复制代码

3.3 更新数据

  1. -- 更新单条
  2. UPDATE employees
  3. SET salary = salary * 1.1,
  4. updated_at = NOW()
  5. WHERE id = 1;
  6. -- 批量更新
  7. UPDATE employees
  8. SET salary = salary * 1.05
  9. WHERE department_id = 1
  10. AND hire_date < '2020-01-01';
  11. -- 多表更新
  12. UPDATE employees e
  13. JOIN departments d ON e.department_id = d.id
  14. SET e.salary = e.salary * 1.1
  15. WHERE d.name = '技术部';
  16. -- 使用子查询更新
  17. UPDATE employees
  18. SET salary = salary + 1000
  19. WHERE id IN (
  20. SELECT id FROM (
  21. SELECT id FROM employees
  22. WHERE performance_score > 90
  23. ) AS tmp
  24. );
复制代码

3.4 删除数据

  1. -- 删除指定数据
  2. DELETE FROM employees WHERE id = 1;
  3. -- 批量删除
  4. DELETE FROM employees WHERE hire_date < '2010-01-01';
  5. -- 多表删除
  6. DELETE e, d
  7. FROM employees e
  8. JOIN departments d ON e.department_id = d.id
  9. WHERE d.status = 'inactive';
  10. -- 使用子查询删除
  11. DELETE FROM employees
  12. WHERE department_id IN (
  13. SELECT id FROM departments WHERE status = 'closed'
  14. );
  15. -- 清空表(不可恢复)
  16. TRUNCATE TABLE employees;
复制代码

四、索引管理

4.1 索引类型

  1. -- 主键索引
  2. CREATE TABLE users (
  3. id INT PRIMARY KEY AUTO_INCREMENT,
  4. name VARCHAR(50)
  5. );
  6. -- 唯一索引
  7. CREATE UNIQUE INDEX uk_email ON users(email);
  8. -- 普通索引
  9. CREATE INDEX idx_name ON users(name);
  10. CREATE INDEX idx_name_dob ON users(name, birth_date);
  11. -- 全文索引
  12. CREATE FULLTEXT INDEX ft_content ON articles(content);
  13. -- 空间索引
  14. CREATE SPATIAL INDEX sp_location ON locations(coordinates);
  15. -- 前缀索引
  16. CREATE INDEX idx_name_prefix ON users(name(20));
  17. -- 组合索引
  18. CREATE INDEX idx_composite ON orders(user_id, order_date, status);
复制代码

4.2 索引管理命令

  1. -- 查看索引
  2. SHOW INDEX FROM users;
  3. SHOW INDEXES FROM users;
  4. SHOW KEYS FROM users;
  5. -- 分析索引使用
  6. ANALYZE TABLE users;
  7. EXPLAIN SELECT * FROM users WHERE name = '张三';
  8. -- 优化表(重建索引)
  9. OPTIMIZE TABLE users;
  10. -- 强制使用索引
  11. SELECT * FROM users
  12. FORCE INDEX (idx_name)
  13. WHERE name LIKE '张%';
  14. -- 忽略索引
  15. SELECT * FROM users
  16. IGNORE INDEX (idx_name)
  17. WHERE name = '张三';
  18. -- 重建索引
  19. ALTER TABLE users DROP INDEX idx_name;
  20. ALTER TABLE users ADD INDEX idx_name (name);
复制代码

五、事务管理

5.1 事务基本操作

  1. -- 开启事务
  2. START TRANSACTION;
  3. -- 或
  4. BEGIN;
  5. -- 或
  6. BEGIN WORK;
  7. -- 提交事务
  8. COMMIT;
  9. -- 回滚事务
  10. ROLLBACK;
  11. -- 保存点
  12. START TRANSACTION;
  13. INSERT INTO table1 VALUES (1, 'test');
  14. SAVEPOINT sp1;
  15. INSERT INTO table2 VALUES (1, 'test');
  16. ROLLBACK TO SAVEPOINT sp1; -- 回滚到保存点
  17. COMMIT;
  18. -- 设置事务隔离级别
  19. SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
  20. START TRANSACTION;
  21. -- 事务操作
  22. COMMIT;
复制代码

5.2 事务隔离级别

  1. -- 查看隔离级别
  2. SELECT @@transaction_isolation;
  3. SELECT @@global.transaction_isolation;
  4. SELECT @@session.transaction_isolation;
  5. -- 设置隔离级别
  6. -- 1. READ UNCOMMITTED(读未提交)
  7. -- 2. READ COMMITTED(读已提交)
  8. -- 3. REPEATABLE READ(可重复读)- MySQL默认
  9. -- 4. SERIALIZABLE(串行化)
  10. -- 会话级别
  11. SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
  12. -- 全局级别
  13. SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
  14. -- 在my.cnf中设置
  15. [mysqld]
  16. transaction-isolation = READ-COMMITTED
复制代码

六、存储过程与函数

6.1 存储过程

  1. -- 创建存储过程
  2. DELIMITER $$
  3. CREATE PROCEDURE GetEmployeeCountByDept(
  4. IN dept_id INT,
  5. OUT emp_count INT
  6. )
  7. BEGIN
  8. DECLARE v_count INT DEFAULT 0;
  9. -- 业务逻辑
  10. SELECT COUNT(*) INTO v_count
  11. FROM employees
  12. WHERE department_id = dept_id;
  13. -- 输出参数
  14. SET emp_count = v_count;
  15. -- 返回结果集
  16. SELECT * FROM employees
  17. WHERE department_id = dept_id;
  18. END$$
  19. DELIMITER ;
  20. -- 调用存储过程
  21. CALL GetEmployeeCountByDept(1, @count);
  22. SELECT @count;
  23. -- 删除存储过程
  24. DROP PROCEDURE IF EXISTS GetEmployeeCountByDept;
  25. -- 查看存储过程
  26. SHOW PROCEDURE STATUS;
  27. SHOW CREATE PROCEDURE GetEmployeeCountByDept;
复制代码

6.2 函数

  1. -- 创建函数
  2. DELIMITER $$
  3. CREATE FUNCTION CalculateBonus(
  4. salary DECIMAL(10,2),
  5. performance_rate DECIMAL(5,2)
  6. ) RETURNS DECIMAL(10,2)
  7. DETERMINISTIC
  8. READS SQL DATA
  9. BEGIN
  10. DECLARE bonus DECIMAL(10,2);
  11. IF performance_rate >= 1.2 THEN
  12. SET bonus = salary * 0.3;
  13. ELSEIF performance_rate >= 1.0 THEN
  14. SET bonus = salary * 0.2;
  15. ELSE
  16. SET bonus = salary * 0.1;
  17. END IF;
  18. RETURN ROUND(bonus, 2);
  19. END$$
  20. DELIMITER ;
  21. -- 使用函数
  22. SELECT
  23. name,
  24. salary,
  25. CalculateBonus(salary, 1.5) AS bonus
  26. FROM employees;
  27. -- 查看函数
  28. SHOW FUNCTION STATUS;
  29. SHOW CREATE FUNCTION CalculateBonus;
复制代码

七、触发器

  1. -- 创建触发器
  2. DELIMITER $$
  3. CREATE TRIGGER before_employee_update
  4. BEFORE UPDATE ON employees
  5. FOR EACH ROW
  6. BEGIN
  7. -- 记录修改历史
  8. INSERT INTO employee_history (
  9. employee_id,
  10. old_salary,
  11. new_salary,
  12. change_time
  13. ) VALUES (
  14. OLD.id,
  15. OLD.salary,
  16. NEW.salary,
  17. NOW()
  18. );
  19. -- 自动更新修改时间
  20. SET NEW.updated_at = NOW();
  21. END$$
  22. DELIMITER ;
  23. -- 创建审计触发器
  24. CREATE TRIGGER audit_employee_changes
  25. AFTER INSERT OR UPDATE OR DELETE ON employees
  26. FOR EACH ROW
  27. BEGIN
  28. DECLARE action_type VARCHAR(10);
  29. IF INSERTING THEN
  30. SET action_type = 'INSERT';
  31. INSERT INTO audit_log (
  32. table_name,
  33. record_id,
  34. action,
  35. old_data,
  36. new_data,
  37. changed_by,
  38. change_time
  39. ) VALUES (
  40. 'employees',
  41. NEW.id,
  42. action_type,
  43. NULL,
  44. JSON_OBJECT(
  45. 'name', NEW.name,
  46. 'salary', NEW.salary
  47. ),
  48. USER(),
  49. NOW()
  50. );
  51. ELSEIF UPDATING THEN
  52. SET action_type = 'UPDATE';
  53. INSERT INTO audit_log (
  54. table_name,
  55. record_id,
  56. action,
  57. old_data,
  58. new_data,
  59. changed_by,
  60. change_time
  61. ) VALUES (
  62. 'employees',
  63. OLD.id,
  64. action_type,
  65. JSON_OBJECT(
  66. 'name', OLD.name,
  67. 'salary', OLD.salary
  68. ),
  69. JSON_OBJECT(
  70. 'name', NEW.name,
  71. 'salary', NEW.salary
  72. ),
  73. USER(),
  74. NOW()
  75. );
  76. ELSEIF DELETING THEN
  77. SET action_type = 'DELETE';
  78. INSERT INTO audit_log (
  79. table_name,
  80. record_id,
  81. action,
  82. old_data,
  83. new_data,
  84. changed_by,
  85. change_time
  86. ) VALUES (
  87. 'employees',
  88. OLD.id,
  89. action_type,
  90. JSON_OBJECT(
  91. 'name', OLD.name,
  92. 'salary', OLD.salary
  93. ),
  94. NULL,
  95. USER(),
  96. NOW()
  97. );
  98. END IF;
  99. END$$
  100. DELIMITER ;
  101. -- 查看触发器
  102. SHOW TRIGGERS;
  103. SHOW CREATE TRIGGER before_employee_update;
  104. -- 删除触发器
  105. DROP TRIGGER IF EXISTS before_employee_update;
复制代码

八、用户与权限管理

8.1 用户管理

  1. -- 创建用户
  2. CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
  3. CREATE USER 'username'@'%' IDENTIFIED BY 'password'; -- 允许远程
  4. CREATE USER 'username'@'192.168.1.%' IDENTIFIED BY 'password'; -- 指定IP段
  5. -- 修改用户名
  6. RENAME USER 'old_user'@'localhost' TO 'new_user'@'localhost';
  7. -- 修改密码
  8. ALTER USER 'username'@'localhost' IDENTIFIED BY 'new_password';
  9. -- MySQL 8.0+
  10. ALTER USER 'username'@'localhost'
  11. IDENTIFIED WITH mysql_native_password BY 'password';
  12. -- 删除用户
  13. DROP USER 'username'@'localhost';
  14. -- 查看用户
  15. SELECT user, host FROM mysql.user;
  16. SELECT * FROM mysql.user WHERE user = 'username';
  17. -- 查看当前用户
  18. SELECT CURRENT_USER();
  19. SELECT USER();
复制代码

8.2 权限管理

  1. -- 授予权限
  2. -- 语法:GRANT 权限 ON 数据库.表 TO 用户@主机
  3. -- 授予所有权限
  4. GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost';
  5. -- 授予数据库所有权限
  6. GRANT ALL PRIVILEGES ON mydb.* TO 'user'@'localhost';
  7. -- 授予特定表权限
  8. GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.employees TO 'user'@'localhost';
  9. -- 授予列级权限
  10. GRANT SELECT (id, name), UPDATE (name) ON mydb.employees TO 'user'@'localhost';
  11. -- 授予存储过程权限
  12. GRANT EXECUTE ON PROCEDURE mydb.GetEmployeeCount TO 'user'@'localhost';
  13. -- 创建角色
  14. CREATE ROLE 'read_only', 'read_write', 'admin';
  15. -- 为角色授权
  16. GRANT SELECT ON mydb.* TO 'read_only';
  17. GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'read_write';
  18. GRANT ALL PRIVILEGES ON *.* TO 'admin';
  19. -- 将角色授予用户
  20. GRANT 'read_only' TO 'user'@'localhost';
  21. SET DEFAULT ROLE 'read_only' TO 'user'@'localhost';
  22. -- 查看权限
  23. SHOW GRANTS FOR 'user'@'localhost';
  24. SELECT * FROM mysql.user WHERE user = 'username';
  25. SELECT * FROM mysql.db WHERE user = 'username';
  26. -- 查看当前用户权限
  27. SHOW GRANTS;
  28. -- 撤销权限
  29. REVOKE INSERT ON mydb.* FROM 'user'@'localhost';
  30. -- 刷新权限
  31. FLUSH PRIVILEGES;
复制代码

九、备份与恢复

9.1 备份方法

  1. # 1. mysqldump 逻辑备份
  2. # 备份整个数据库
  3. mysqldump -u root -p --all-databases > backup.sql
  4. # 备份指定数据库
  5. mysqldump -u root -p mydb > mydb_backup.sql
  6. # 备份指定表
  7. mysqldump -u root -p mydb employees departments > tables_backup.sql
  8. # 备份结构
  9. mysqldump -u root -p --no-data mydb > mydb_structure.sql
  10. # 备份数据
  11. mysqldump -u root -p --no-create-info mydb > mydb_data.sql
  12. # 压缩备份
  13. mysqldump -u root -p mydb | gzip > mydb_backup.sql.gz
  14. # 2. 二进制日志备份
  15. # 查看当前二进制日志
  16. SHOW BINARY LOGS;
  17. SHOW MASTER STATUS;
  18. # 备份二进制日志
  19. mysqlbinlog mysql-bin.000001 > binlog_backup.sql
  20. # 3. 物理备份(InnoDB)
  21. # 使用Percona XtraBackup
  22. innobackupex --user=root --password=xxx /backup/
复制代码

9.2 恢复方法

  1. # 恢复整个数据库
  2. mysql -u root -p < backup.sql
  3. # 恢复指定数据库
  4. mysql -u root -p mydb < mydb_backup.sql
  5. # 恢复压缩备份
  6. gunzip < mydb_backup.sql.gz | mysql -u root -p mydb
  7. # 恢复二进制日志
  8. mysqlbinlog mysql-bin.000001 | mysql -u root -p
  9. # 从特定位置恢复
  10. mysqlbinlog --start-position=107 mysql-bin.000001 | mysql -u root -p
复制代码

十、性能优化

10.1 查询优化

  1. -- 使用EXPLAIN分析查询
  2. EXPLAIN SELECT * FROM employees WHERE name = '张三';
  3. -- 更详细的执行计划
  4. EXPLAIN FORMAT=JSON
  5. SELECT * FROM employees WHERE name = '张三';
  6. -- 分析查询性能
  7. EXPLAIN ANALYZE
  8. SELECT * FROM employees WHERE name = '张三';
  9. -- 优化建议
  10. -- 1. 避免SELECT *
  11. SELECT id, name, salary FROM employees;
  12. -- 2. 使用索引覆盖
  13. CREATE INDEX idx_covering ON employees(department_id, salary, name);
  14. SELECT department_id, salary, name FROM employees
  15. WHERE department_id = 1;
  16. -- 3. 避免在WHERE子句中使用函数
  17. -- 不推荐
  18. SELECT * FROM employees WHERE YEAR(hire_date) = 2023;
  19. -- 推荐
  20. SELECT * FROM employees
  21. WHERE hire_date >= '2023-01-01' AND hire_date < '2024-01-01';
  22. -- 4. 使用LIMIT
  23. SELECT * FROM employees ORDER BY id LIMIT 1000;
  24. -- 5. 批量操作
  25. INSERT INTO employees (name, salary) VALUES
  26. ('张三', 10000),
  27. ('李四', 12000),
  28. ('王五', 15000);
复制代码

10.2 索引优化

  1. -- 查看索引使用情况
  2. SELECT
  3. table_name,
  4. index_name,
  5. stat_value * @@innodb_page_size / 1024 / 1024 AS index_size_mb
  6. FROM mysql.innodb_index_stats
  7. WHERE database_name = 'mydb';
  8. -- 查找未使用的索引
  9. SELECT
  10. object_schema,
  11. object_name,
  12. index_name
  13. FROM performance_schema.table_io_waits_summary_by_index_usage
  14. WHERE index_name IS NOT NULL
  15. AND count_star = 0
  16. AND object_schema NOT IN ('mysql', 'sys', 'performance_schema');
  17. -- 删除冗余索引
  18. -- 查找(a,b)和(a)的索引,删除(a)
  19. SELECT
  20. a.TABLE_SCHEMA,
  21. a.TABLE_NAME,
  22. a.INDEX_NAME AS redundant_index,
  23. b.INDEX_NAME AS dominant_index
  24. FROM information_schema.STATISTICS a
  25. JOIN information_schema.STATISTICS b
  26. WHERE a.TABLE_SCHEMA = b.TABLE_SCHEMA
  27. AND a.TABLE_NAME = b.TABLE_NAME
  28. AND a.SEQ_IN_INDEX = b.SEQ_IN_INDEX
  29. AND a.COLUMN_NAME = b.COLUMN_NAME
  30. AND a.INDEX_NAME != b.INDEX_NAME
  31. AND a.NON_UNIQUE = 1
  32. AND b.NON_UNIQUE = 1
  33. AND a.INDEX_NAME LIKE 'idx%';
复制代码

十一、监控与诊断

11.1 状态查看

  1. -- 查看服务器状态
  2. SHOW STATUS;
  3. SHOW GLOBAL STATUS;
  4. SHOW SESSION STATUS;
  5. -- 查看变量
  6. SHOW VARIABLES;
  7. SHOW GLOBAL VARIABLES LIKE '%buffer%';
  8. -- 查看进程列表
  9. SHOW PROCESSLIST;
  10. SHOW FULL PROCESSLIST;
  11. -- 查看锁信息
  12. SHOW ENGINE INNODB STATUS;
  13. SELECT * FROM information_schema.INNODB_LOCKS;
  14. SELECT * FROM information_schema.INNODB_LOCK_WAITS;
  15. -- 查看表状态
  16. SHOW TABLE STATUS LIKE 'employees';
  17. ANALYZE TABLE employees; -- 更新统计信息
复制代码

11.2 性能监控

  1. -- 慢查询日志
  2. -- 在my.cnf中配置
  3. slow_query_log = 1
  4. slow_query_log_file = /var/log/mysql/slow.log
  5. long_query_time = 2
  6. log_queries_not_using_indexes = 1
  7. -- 查看慢查询
  8. SHOW VARIABLES LIKE 'slow_query_log%';
  9. SHOW VARIABLES LIKE 'long_query_time';
  10. -- 使用performance_schema
  11. SELECT * FROM performance_schema.events_statements_summary_by_digest
  12. ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
  13. -- 查看等待事件
  14. SELECT
  15. event_name,
  16. count_star,
  17. sum_timer_wait/1000000000 as total_wait_sec,
  18. avg_timer_wait/1000000000 as avg_wait_sec
  19. FROM performance_schema.events_waits_summary_global_by_event_name
  20. WHERE count_star > 0
  21. ORDER BY sum_timer_wait DESC LIMIT 10;
复制代码

十二、高级功能

12.1 窗口函数

  1. -- 排名函数
  2. SELECT
  3. name,
  4. salary,
  5. department_id,
  6. ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num,
  7. RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank_num,
  8. DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank_num
  9. FROM employees;
  10. -- 聚合窗口函数
  11. SELECT
  12. name,
  13. salary,
  14. department_id,
  15. AVG(salary) OVER (PARTITION BY department_id) AS dept_avg_salary,
  16. SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_date) AS running_total,
  17. FIRST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_max_salary
  18. FROM employees;
  19. -- 移动平均
  20. SELECT
  21. order_date,
  22. amount,
  23. AVG(amount) OVER (ORDER BY order_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
  24. FROM orders;
复制代码

12.2 JSON操作

  1. -- 创建JSON字段
  2. CREATE TABLE products (
  3. id INT PRIMARY KEY,
  4. name VARCHAR(100),
  5. attributes JSON,
  6. metadata JSON
  7. );
  8. -- 插入JSON数据
  9. INSERT INTO products VALUES (
  10. 1,
  11. '手机',
  12. '{"brand": "Apple", "color": "black", "storage": 128}',
  13. '{"tags": ["new", "hot"], "rating": 4.5}'
  14. );
  15. -- 查询JSON
  16. SELECT
  17. name,
  18. attributes->'$.brand' AS brand,
  19. JSON_EXTRACT(attributes, '$.color') AS color,
  20. metadata->'$.rating' AS rating
  21. FROM products;
  22. -- JSON路径查询
  23. SELECT *
  24. FROM products
  25. WHERE JSON_EXTRACT(attributes, '$.brand') = 'Apple';
  26. -- 更新JSON
  27. UPDATE products
  28. SET attributes = JSON_SET(attributes, '$.price', 6999)
  29. WHERE id = 1;
  30. -- JSON函数
  31. SELECT
  32. JSON_TYPE(attributes) AS type,
  33. JSON_LENGTH(attributes) AS length,
  34. JSON_KEYS(attributes) AS keys,
  35. JSON_VALID(attributes) AS is_valid
  36. FROM products;
复制代码

十三、维护命令

13.1 数据库维护

  1. -- 优化表
  2. OPTIMIZE TABLE employees;
  3. OPTIMIZE LOCAL TABLE employees; -- 在线优化
  4. -- 修复表
  5. REPAIR TABLE employees;
  6. REPAIR TABLE employees QUICK;
  7. -- 检查表
  8. CHECK TABLE employees;
  9. CHECK TABLE employees FAST;
  10. CHECK TABLE employees CHANGED;
  11. -- 分析表
  12. ANALYZE TABLE employees;
  13. ANALYZE LOCAL TABLE employees;
  14. -- 更新统计信息
  15. ANALYZE TABLE employees UPDATE HISTOGRAM ON salary WITH 100 BUCKETS;
  16. -- 重建表
  17. ALTER TABLE employees ENGINE=InnoDB;
复制代码

13.2 系统维护

  1. # 导出数据
  2. mysqldump -u root -p mydb employees > employees.sql
  3. # 导入数据
  4. mysql -u root -p mydb < employees.sql
  5. # 批量执行SQL
  6. mysql -u root -p -e "SHOW DATABASES; SHOW TABLES;"
  7. # 定时备份脚本
  8. #!/bin/bash
  9. BACKUP_DIR="/backup/mysql"
  10. DATE=$(date +%Y%m%d_%H%M%S)
  11. mysqldump -u root -p'password' --all-databases | gzip > $BACKUP_DIR/backup_$DATE.sql.gz
  12. # 保留最近7天备份
  13. find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
复制代码

十四、安全最佳实践

14.1 安全设置

  1. -- 删除匿名用户
  2. DELETE FROM mysql.user WHERE User = '';
  3. FLUSH PRIVILEGES;
  4. -- 限制root远程登录
  5. DELETE FROM mysql.user WHERE User = 'root' AND Host NOT IN ('localhost', '127.0.0.1');
  6. FLUSH PRIVILEGES;
  7. -- 创建应用程序专用用户
  8. CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'StrongPassword123!';
  9. GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'192.168.1.%';
  10. -- 定期更改密码
  11. ALTER USER 'app_user'@'192.168.1.%' PASSWORD EXPIRE INTERVAL 90 DAY;
  12. -- 查看用户权限
  13. SHOW GRANTS FOR 'app_user'@'192.168.1.%';
  14. -- 设置密码策略
  15. SET GLOBAL validate_password.policy = 2; -- STRONG
  16. SET GLOBAL validate_password.length = 12;
  17. SET GLOBAL validate_password.number_count = 2;
  18. SET GLOBAL validate_password.special_char_count = 1;
复制代码

十五、故障排查

15.1 常见问题解决

  1. -- 1. 连接数过多
  2. SHOW PROCESSLIST;
  3. SHOW STATUS LIKE 'Threads_connected';
  4. SHOW VARIABLES LIKE 'max_connections';
  5. -- 临时增加连接数
  6. SET GLOBAL max_connections = 1000;
  7. -- 2. 死锁检查
  8. SHOW ENGINE INNODB STATUS;
  9. SELECT * FROM information_schema.INNODB_LOCKS;
  10. SELECT * FROM information_schema.INNODB_LOCK_WAITS;
  11. -- 3. 慢查询分析
  12. SHOW VARIABLES LIKE 'slow_query_log%';
  13. SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;
  14. -- 4. 表损坏修复
  15. CHECK TABLE employees;
  16. REPAIR TABLE employees;
  17. -- 5. 重置root密码
  18. # 停止MySQL服务
  19. # 启动跳过授权
  20. mysqld_safe --skip-grant-tables &
  21. # 修改密码
  22. ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPassword';
  23. # 重启服务
复制代码

十六、实用脚本示例

16.1 监控脚本

  1. -- 数据库健康检查
  2. SELECT
  3. VARIABLE_NAME,
  4. VARIABLE_VALUE,
  5. CASE
  6. WHEN VARIABLE_NAME IN ('uptime', 'threads_connected')
  7. THEN VARIABLE_VALUE
  8. WHEN VARIABLE_NAME = 'max_connections'
  9. THEN CONCAT(VARIABLE_VALUE, ' (当前使用率: ',
  10. ROUND((SELECT VARIABLE_VALUE
  11. FROM information_schema.GLOBAL_STATUS
  12. WHERE VARIABLE_NAME = 'Threads_connected') / VARIABLE_VALUE * 100, 2), '%)')
  13. ELSE VARIABLE_VALUE
  14. END AS status
  15. FROM information_schema.GLOBAL_STATUS
  16. WHERE VARIABLE_NAME IN (
  17. 'uptime',
  18. 'threads_connected',
  19. 'max_connections',
  20. 'innodb_buffer_pool_pages_free',
  21. 'questions',
  22. 'slow_queries'
  23. )
  24. UNION ALL
  25. SELECT
  26. 'buffer_pool_hit_rate',
  27. '',
  28. CONCAT(
  29. ROUND((1 -
  30. (SELECT VARIABLE_VALUE
  31. FROM information_schema.GLOBAL_STATUS
  32. WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') /
  33. (SELECT VARIABLE_VALUE
  34. FROM information_schema.GLOBAL_STATUS
  35. WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests')
  36. ) * 100, 2), '%'
  37. )
  38. FROM DUAL;
复制代码

总结

使用建议:

  1. 开发规范

    • 使用InnoDB存储引擎
    • 为每张表设置主键
    • 使用utf8mb4字符集
    • 为频繁查询的列创建索引
    • 避免在数据库中存储大文件
  2. 性能优化

    • 定期分析慢查询
    • 监控连接数和缓冲区使用
    • 定期优化和修复表
    • 使用连接池
  3. 安全建议

    • 使用强密码
    • 定期备份
    • 限制远程访问
    • 定期审计权限
  4. 维护计划

    • 每日监控关键指标
    • 每周备份
    • 每月性能分析
    • 每季度安全审计
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行