Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql用户与权限

MySQL 用户管理和数据库权限问题

作者:平凡的梦

MySQL作为世界上最流行的开源关系型数据库,在实际生产环境中,合理的用户管理和权限控制是确保数据安全的重要基石,本文将从零开始,手把手教你掌握MySQL的用户管理和权限控制,感兴趣的朋友一起看看吧

🎯 前言

MySQL作为世界上最流行的开源关系型数据库,在实际生产环境中,合理的用户管理和权限控制是确保数据安全的重要基石。本文将从零开始,手把手教你掌握MySQL的用户管理和权限控制。

1. 用户管理

1.1 什么是用户管理?

用户管理的定义和重要性

用户管理是指在MySQL数据库中创建、删除、修改用户账户,并为这些账户分配适当权限的过程。就像公司的门禁系统一样,不同的员工需要不同的门卡权限,有些人只能进入普通办公区,有些人可以进入机房,而管理员则拥有所有区域的访问权限。

为什么用户管理如此重要?

MySQL默认使用的root账户及其权限

MySQL安装后默认创建一个超级管理员账户root,这个账户拥有最高权限,可以:

-- 查看当前用户
SELECT USER();
-- 查看当前用户的权限
SHOW GRANTS;
-- 以root用户身份查看所有权限
SHOW GRANTS FOR 'root'@'localhost';

1.2 用户信息

MySQL用户信息存储的位置

MySQL将所有用户信息存储在系统数据库mysqluser表中。这个表包含了用户名、主机、密码哈希值以及各种权限信息。

-- 切换到mysql系统数据库
USE mysql;
-- 查看user表的结构
DESC user;
-- 查看user表的主要字段
SELECT Host, User, authentication_string FROM user;

查询用户信息的方法

-- 方法1:查看所有用户
SELECT Host, User FROM mysql.user;
-- 方法2:查看当前数据库的所有用户
SELECT DISTINCT User FROM mysql.user;
-- 方法3:查看特定用户的详细信息
SELECT Host, User, authentication_string, 
       Select_priv, Insert_priv, Update_priv, Delete_priv
FROM mysql.user 
WHERE User = 'root';
-- 方法4:使用SHOW命令查看用户权限
SHOW GRANTS FOR 'root'@'localhost';

1.3 创建用户

创建用户的命令和语法

-- 基本语法
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
-- 完整语法
CREATE USER [IF NOT EXISTS] '用户名'@'主机名' 
IDENTIFIED BY '密码' 
[PASSWORD EXPIRE [DEFAULT | NEVER | INTERVAL N DAY]]
[ACCOUNT [LOCK | UNLOCK]];

主机名说明:

创建用户时设置密码的加密处理

MySQL会自动对密码进行哈希加密,不会以明文形式存储。从MySQL 8.0开始,默认使用caching_sha2_password插件。

-- 查看默认的密码验证插件
SHOW VARIABLES LIKE 'default_authentication_plugin';
-- 创建用户时指定密码验证插件
CREATE USER 'test_user'@'localhost' 
IDENTIFIED WITH mysql_native_password BY 'password123';

创建用户示例

-- 示例1:创建只能本机登录的用户
CREATE USER 'local_user'@'localhost' IDENTIFIED BY 'local_pass123';
-- 示例2:创建可从任意主机登录的用户
CREATE USER 'remote_user'@'%' IDENTIFIED BY 'remote_pass123';
-- 示例3:创建只能从特定IP登录的用户
CREATE USER 'office_user'@'192.168.1.100' IDENTIFIED BY 'office_pass123';
-- 示例4:创建只能从特定网段登录的用户
CREATE USER 'dept_user'@'192.168.1.%' IDENTIFIED BY 'dept_pass123';
-- 示例5:创建用户并设置密码永不过期
CREATE USER 'app_user'@'%' 
IDENTIFIED BY 'app_pass123' 
PASSWORD EXPIRE NEVER;
-- 验证用户创建成功
SELECT Host, User FROM mysql.user WHERE User LIKE '%user%';

创建用户时常见报错的解决方法

-- 错误1:ERROR 1396 (HY000): Operation CREATE USER failed
-- 原因:用户已经存在
-- 解决方法:使用IF NOT EXISTS或先删除用户
CREATE USER IF NOT EXISTS 'existing_user'@'localhost' IDENTIFIED BY 'password';
-- 错误2:ERROR 1045 (28000): Access denied
-- 原因:当前用户没有CREATE USER权限
-- 解决方法:使用有足够权限的用户(如root)登录
-- 错误3:密码策略不符合要求
-- 查看密码策略
SHOW VARIABLES LIKE 'validate_password%';
-- 创建符合密码策略的用户
CREATE USER 'strong_user'@'localhost' IDENTIFIED BY 'StrongPass123!';

1.4 删除用户

删除用户的命令和语法

-- 基本语法
DROP USER '用户名'@'主机名';
-- 删除多个用户
DROP USER '用户1'@'主机1', '用户2'@'主机2';
-- 安全删除(如果用户不存在不会报错)
DROP USER IF EXISTS '用户名'@'主机名';

删除用户示例

-- 示例1:删除单个用户
DROP USER 'test_user'@'localhost';
-- 示例2:删除多个用户
DROP USER 'user1'@'localhost', 'user2'@'%';
-- 示例3:安全删除用户
DROP USER IF EXISTS 'maybe_not_exist'@'localhost';
-- 示例4:删除所有测试用户
-- 先查询要删除的用户
SELECT CONCAT('DROP USER ''', User, '''@''', Host, ''';') AS drop_command
FROM mysql.user 
WHERE User LIKE 'test_%';
-- 执行生成的删除命令
DROP USER 'test_user1'@'localhost';
DROP USER 'test_user2'@'%';
-- 验证用户删除成功
SELECT Host, User FROM mysql.user WHERE User LIKE 'test_%';

1.5 修改用户的密码

修改用户密码的命令和语法

-- 方法1:使用ALTER USER(推荐,MySQL 5.7+)
ALTER USER '用户名'@'主机名' IDENTIFIED BY '新密码';
-- 方法2:使用SET PASSWORD
SET PASSWORD FOR '用户名'@'主机名' = '新密码';
-- 方法3:修改当前用户密码
ALTER USER USER() IDENTIFIED BY '新密码';
-- 或者
SET PASSWORD = '新密码';

使用PASSWORD()函数的注意事项

在MySQL 8.0及以上版本中,PASSWORD()函数已被移除,直接使用明文密码即可,MySQL会自动进行哈希处理。

-- MySQL 5.7及以下版本(已过时,不推荐)
SET PASSWORD FOR 'user'@'host' = PASSWORD('new_password');
-- MySQL 8.0及以上版本(推荐)
ALTER USER 'user'@'host' IDENTIFIED BY 'new_password';

修改用户密码示例

-- 示例1:root用户修改其他用户密码
ALTER USER 'app_user'@'%' IDENTIFIED BY 'new_strong_password123!';
-- 示例2:用户修改自己的密码
ALTER USER USER() IDENTIFIED BY 'my_new_password123!';
-- 示例3:修改密码并设置过期策略
ALTER USER 'temp_user'@'localhost' 
IDENTIFIED BY 'temp_password123!' 
PASSWORD EXPIRE INTERVAL 30 DAY;
-- 示例4:强制用户下次登录时修改密码
ALTER USER 'new_employee'@'%' 
IDENTIFIED BY 'initial_password123!' 
PASSWORD EXPIRE;
-- 示例5:批量修改密码(生成SQL语句)
SELECT CONCAT('ALTER USER ''', User, '''@''', Host, ''' IDENTIFIED BY ''new_password_', User, ''';') AS alter_command
FROM mysql.user 
WHERE User LIKE 'temp_%';
-- 验证密码修改(通过重新登录测试)
-- mysql -u app_user -p -h localhost

2. 数据库的权限

2.1 数据库的权限列表

MySQL提供了细粒度的权限控制,可以在不同级别设置权限:全局级别、数据库级别、表级别、列级别。

常见权限及其上下文

权限名称权限描述适用范围使用场景
ALL PRIVILEGES所有权限(除GRANT OPTION外)全局、数据库、表管理员用户
SELECT查询数据数据库、表、列只读用户、报表用户
INSERT插入数据数据库、表、列数据录入员
UPDATE更新数据数据库、表、列数据维护员
DELETE删除数据数据库、表数据管理员
CREATE创建数据库、表全局、数据库开发人员
DROP删除数据库、表全局、数据库高级管理员
ALTER修改表结构数据库、表数据库设计师
INDEX创建、删除索引数据库、表性能优化人员
GRANT OPTION授权给其他用户对应权限范围权限管理员
CREATE USER创建用户全局用户管理员
RELOAD重新加载权限表全局系统管理员
SHUTDOWN关闭MySQL服务全局系统管理员
PROCESS查看所有进程全局监控人员
FILE读写服务器文件全局数据导入导出人员
-- 查看所有可用权限
SHOW PRIVILEGES;
-- 查看当前用户权限
SHOW GRANTS;
-- 查看特定用户权限
SHOW GRANTS FOR 'username'@'hostname';

2.2 给用户权限

给用户授权的命令和语法

-- 基本语法
GRANT 权限列表 ON 数据库.表 TO '用户名'@'主机名';
-- 完整语法
GRANT 权限列表 ON 数据库.表 TO '用户名'@'主机名' 
[WITH GRANT OPTION] 
[WITH MAX_QUERIES_PER_HOUR count]
[WITH MAX_UPDATES_PER_HOUR count]
[WITH MAX_CONNECTIONS_PER_HOUR count];

权限列表的指定方式

-- 单个权限
GRANT SELECT ON database.table TO 'user'@'host';
-- 多个权限
GRANT SELECT, INSERT, UPDATE ON database.table TO 'user'@'host';
-- 所有权限
GRANT ALL PRIVILEGES ON database.table TO 'user'@'host';
-- 特定列权限
GRANT SELECT (column1, column2), UPDATE (column1) ON database.table TO 'user'@'host';

给用户授权示例

-- 创建测试环境
CREATE DATABASE company_db;
USE company_db;
CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE,
    department VARCHAR(50),
    salary DECIMAL(10,2)
);
CREATE TABLE departments (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    manager VARCHAR(100)
);
-- 示例1:授予数据库的所有权限
CREATE USER 'db_admin'@'localhost' IDENTIFIED BY 'admin_pass123!';
GRANT ALL PRIVILEGES ON company_db.* TO 'db_admin'@'localhost';
-- 示例2:授予只读权限
CREATE USER 'report_user'@'%' IDENTIFIED BY 'report_pass123!';
GRANT SELECT ON company_db.* TO 'report_user'@'%';
-- 示例3:授予特定表的增删改查权限
CREATE USER 'hr_user'@'192.168.1.%' IDENTIFIED BY 'hr_pass123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON company_db.employees TO 'hr_user'@'192.168.1.%';
-- 示例4:授予列级别权限
CREATE USER 'public_user'@'%' IDENTIFIED BY 'public_pass123!';
GRANT SELECT (id, name, department) ON company_db.employees TO 'public_user'@'%';
-- 示例5:授予创建表权限
CREATE USER 'developer'@'localhost' IDENTIFIED BY 'dev_pass123!';
GRANT CREATE, ALTER, INDEX ON company_db.* TO 'developer'@'localhost';
GRANT SELECT, INSERT, UPDATE, DELETE ON company_db.* TO 'developer'@'localhost';
-- 示例6:授予全局权限
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'backup_pass123!';
GRANT SELECT ON *.* TO 'backup_user'@'localhost';
GRANT RELOAD, LOCK TABLES ON *.* TO 'backup_user'@'localhost';
-- 示例7:授予权限并允许转授(WITH GRANT OPTION)
CREATE USER 'team_lead'@'%' IDENTIFIED BY 'lead_pass123!';
GRANT SELECT, INSERT, UPDATE ON company_db.* TO 'team_lead'@'%' WITH GRANT OPTION;
-- 示例8:授予权限并设置资源限制
CREATE USER 'limited_user'@'%' IDENTIFIED BY 'limited_pass123!';
GRANT SELECT ON company_db.* TO 'limited_user'@'%' 
WITH MAX_QUERIES_PER_HOUR 1000 
WITH MAX_CONNECTIONS_PER_HOUR 10;
-- 刷新权限表(使权限立即生效)
FLUSH PRIVILEGES;
-- 验证权限授予成功
SHOW GRANTS FOR 'db_admin'@'localhost';
SHOW GRANTS FOR 'report_user'@'%';
SHOW GRANTS FOR 'hr_user'@'192.168.1.%';

2.3 回收权限

回收用户权限的命令和语法

-- 基本语法
REVOKE 权限列表 ON 数据库.表 FROM '用户名'@'主机名';
-- 回收所有权限
REVOKE ALL PRIVILEGES ON 数据库.表 FROM '用户名'@'主机名';
-- 回收GRANT权限
REVOKE GRANT OPTION ON 数据库.表 FROM '用户名'@'主机名';

回收权限示例

-- 示例1:回收特定权限
REVOKE INSERT, UPDATE ON company_db.employees FROM 'hr_user'@'192.168.1.%';
-- 示例2:回收数据库的所有权限
REVOKE ALL PRIVILEGES ON company_db.* FROM 'developer'@'localhost';
-- 示例3:回收全局权限
REVOKE RELOAD ON *.* FROM 'backup_user'@'localhost';
-- 示例4:回收GRANT权限
REVOKE GRANT OPTION ON company_db.* FROM 'team_lead'@'%';
-- 示例5:回收列级别权限
REVOKE SELECT (salary) ON company_db.employees FROM 'public_user'@'%';
-- 示例6:完全移除用户的所有权限
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'limited_user'@'%';
-- 刷新权限表
FLUSH PRIVILEGES;
-- 验证权限回收成功
SHOW GRANTS FOR 'hr_user'@'192.168.1.%';
SHOW GRANTS FOR 'developer'@'localhost';

🚨 安全最佳实践

1. 密码安全策略

-- 查看密码策略
SHOW VARIABLES LIKE 'validate_password%';
-- 创建强密码用户示例
CREATE USER 'secure_user'@'localhost' IDENTIFIED BY 'SecurePass123!@#';

2. 权限最小化原则

-- ❌ 错误做法:给予过多权限
GRANT ALL PRIVILEGES ON *.* TO 'app_user'@'%';
-- ✅ 正确做法:只给必要权限
GRANT SELECT, INSERT, UPDATE ON specific_db.specific_table TO 'app_user'@'%';

3. 定期权限审计

-- 查看所有用户及其基本权限信息
SELECT 
    User, 
    Host,
    Select_priv,
    Insert_priv,
    Update_priv,
    Delete_priv,
    Create_priv,
    Drop_priv
FROM mysql.user
WHERE User != '';
-- 查看特定用户的所有权限
SHOW GRANTS FOR 'username'@'hostname';

4. 连接安全

-- 限制用户连接来源
CREATE USER 'secure_user'@'192.168.1.%' IDENTIFIED BY 'SecurePass123!';
-- 而不是使用 '%' 允许任意IP连接
-- 设置连接限制
ALTER USER 'limited_user'@'%' 
WITH MAX_CONNECTIONS_PER_HOUR 10 
MAX_QUERIES_PER_HOUR 1000;

🎯 总结

MySQL的用户管理和权限控制是数据库安全的基础,掌握这些技能对于数据库管理员和开发人员都至关重要。

核心要点:

记住:安全无小事,权限需谨慎。合理的用户管理和权限控制不仅保护了数据安全,也为系统的稳定运行提供了保障。

到此这篇关于MySQL 用户管理和数据库权限 的文章就介绍到这了,更多相关mysql用户与权限内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文