13. 用户管理【由浅入深-MySQL】

文章目录

  • [第一章 用户与权限体系概述](#第一章 用户与权限体系概述)
  • [第二章 用户创建与属性配置](#第二章 用户创建与属性配置)
    • [2.1 创建用户的基本语法](#2.1 创建用户的基本语法)
      • [2.1.1 密码加密机制](#2.1.1 密码加密机制)
    • [2.2 用户信息存储的本质](#2.2 用户信息存储的本质)
  • [第三章 密码管理与安全策略](#第三章 密码管理与安全策略)
    • [3.1 修改用户密码](#3.1 修改用户密码)
      • [3.1.1 `SET PASSWORD` 与 `PASSWORD()` 函数的兼容性](#3.1.1 SET PASSWORD 与 PASSWORD() 函数的兼容性)
      • [3.1.2 MySQL 8.0 及之后版本的正确做法](#3.1.2 MySQL 8.0 及之后版本的正确做法)
  • [第四章 权限分配与回收](#第四章 权限分配与回收)
    • [4.1 给用户授权(GRANT)](#4.1 给用户授权(GRANT))
    • [4.2 查看用户权限](#4.2 查看用户权限)
    • [4.3 刷新权限(FLUSH PRIVILEGES)](#4.3 刷新权限(FLUSH PRIVILEGES))
    • [4.4 回收用户权限(REVOKE)](#4.4 回收用户权限(REVOKE))
  • [第五章 用户删除与管理](#第五章 用户删除与管理)
    • [5.1 删除用户(DROP USER)](#5.1 删除用户(DROP USER))
      • [5.1.1 关于 `%` 通配符的说明](#5.1.1 关于 % 通配符的说明)
  • [第六章 常见问题排查与特殊场景](#第六章 常见问题排查与特殊场景)
    • [6.1 MySQL 配置参数 `skip-grant-tables` 的影响](#6.1 MySQL 配置参数 skip-grant-tables 的影响)
  • [第七章 最佳实践总结](#第七章 最佳实践总结)

第一章 用户与权限体系概述

在生产环境中,直接使用 root 用户操作数据库是一项高风险行为。root 用户拥有无限权限,一旦密码泄露或发生误操作,后果不堪设想。因此,建立精细化的用户管理与权限控制体系,是数据库安全的第一道防线。

MySQL 将所有用户信息和权限数据存储在系统数据库 mysql 的 user 表中。

这张表是 MySQL 权限体系的核心,我们可以通过查询它来了解当前所有用户的基本情况。

sql 复制代码
-- 切换到 mysql 数据库
USE mysql;

-- 查看用户的基本信息(主机、用户名、密码密文)
SELECT host, user, authentication_string FROM user;

查询结果中的关键字段含义如下:

  • host :表示该用户允许从哪个主机或 IP 登录。localhost 代表仅限本机登录,% 则是通配符,代表允许从任意主机远程登录。
  • user:登录用户名。
  • authentication_string(/ɔːˌθentɪˈkeɪʃən strɪŋ/) :用户密码经过加密算法处理后的密文字符串。

需要注意的是,mysql.user 表中的权限是全局级别 的。一个用户能否连接服务器,取决于 host、user 和 password 这三者的组合是否匹配。

第二章 用户创建与属性配置

2.1 创建用户的基本语法

创建用户的标准 SQL 语句是 CREATE USER。

sql 复制代码
CREATE USER '用户名'@'登录主机/主机名' IDENTIFIED BY '密码';
  • '用户名'@'登录主机/主机名' :这是 MySQL 中用户的唯一标识。MySQL 通过"用户名 + 主机名"的组合来区分不同的账户。如果省略主机名部分,则默认为 '%',即允许从任何主机登录。
  • IDENTIFIED BY '密码':用于设置该用户的登录密码。

2.1.1 密码加密机制

这是一个非常关键的问题。在 CREATE USER 语句中,我们直接输入的是明文密码 。这个明文密码在存入 mysql.user 表的 authentication_string 字段之前,会由 MySQL 服务器自动进行加密处理。

开发者不需要也不应该手动调用加密函数。MySQL 会根据当前配置的认证插件(如 mysql_native_password 或 caching_sha2_password)自动完成加密。

案例:创建一个新用户

sql 复制代码
-- 创建一个名为 'app_user',只允许从本机 (localhost) 登录的用户
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'StrongP@ssw0rd!';

-- 创建一个名为 'remote_user',允许从任何主机 (%) 登录的用户
CREATE USER 'remote_user'@'%' IDENTIFIED BY 'AnotherP@ss!';

-- 查看创建后的用户信息(密码已被自动加密)
SELECT host, user, authentication_string FROM user WHERE user IN ('app_user', 'remote_user');

安全提示: 不要轻易添加一个可以从任意地方登录('%')的用户,这会显著增加被攻击的风险。

2.2 用户信息存储的本质

"创建用户是不是就是在 mysql.user 表里进行 CURD 操作?"这个问题,触及了用户管理的本质。

答案是:从最终效果上看,是的。但官方强烈推荐使用专门的 SQL 语句(如 CREATE USER),而不是直接对 mysql.user 表进行 INSERT、UPDATE 或 DELETE 操作。

直接操作系统表风险极高,容易破坏数据完整性或导致权限系统混乱。使用 CREATE USER、DROP USER 等专用 DDL 语句是更安全、更规范的做法。

第三章 密码管理与安全策略

3.1 修改用户密码

修改用户密码有两种常见场景:

1. 用户修改自己的密码

在 MySQL 5.7 及更早版本中,可以使用:

sql 复制代码
SET PASSWORD = PASSWORD('新密码');

2. 管理员(如 root)修改指定用户的密码

同样,在旧版本中可以使用:

sql 复制代码
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');

3.1.1 SET PASSWORD 与 PASSWORD() 函数的兼容性

"改密码语法在新版本里面是否已失效?"

结论是:在 MySQL 8.0 中,PASSWORD() 函数已被移除,SET PASSWORD ... = PASSWORD('...') 的语法已不再可用。

  • MySQL 5.7 :PASSWORD() 函数已被标记为废弃(deprecated),但仍可使用。
  • MySQL 8.0 :PASSWORD() 函数被彻底移除,上述语法会直接报错。

3.1.2 MySQL 8.0 及之后版本的正确做法

在 MySQL 8.0 中,修改密码统一使用 ALTER USER 用户@主机 IDENTIFIED BY 新密码,普通用户修改自己的密码和管理员修改其他用户密码语法相同,只是权限不同。

sql 复制代码
-- 修改自己的密码
ALTER USER '用户名'@'主机名' IDENTIFIED BY '新密码';

-- root 用户修改指定用户的密码
ALTER USER 'app_user'@'localhost' IDENTIFIED BY 'NewStrongP@ss!';

SET PASSWORD 语句本身在 MySQL 8.0 中并未被完全废弃,但其用法已经改变。现在,SET PASSWORD 在内部会被重写为 ALTER USER 语句。为了更好的兼容性和清晰性,直接使用 ALTER USER 是官方推荐的最佳实践。

第四章 权限分配与回收

4.1 给用户授权(GRANT)

新创建的用户默认没有任何权限。我们需要使用 GRANT 语句来赋予其操作数据库的权限。

授权语法:

sql 复制代码
GRANT 权限列表 ON 库.对象名 TO '用户名'@'登录位置' [IDENTIFIED BY '密码'];
  • 权限列表 :要授予的权限,如 SELECT, INSERT, UPDATE, DELETE 等,多个权限用逗号分隔 。使用 ALL [PRIVILEGES] 表示授予该对象上的所有权限。
  • 库.对象名 :权限作用范围。
    • *.*:代表本系统中的所有数据库及其所有对象。
    • 库名.*:代表指定数据库中的所有对象(表、视图、存储过程等)。
    • 库名.表名:代表指定数据库中的特定表。
  • [IDENTIFIED BY '密码']:可选。如果用户存在,则在授权的同时修改其密码;如果用户不存在,则创建该用户。

案例:授予查询权限

sql 复制代码
-- 使用 root 账号
-- 授予 'app_user'@'localhost' 对 test 数据库下所有表的 SELECT 权限
GRANT SELECT ON test.* TO 'app_user'@'localhost';

-- 授予 'app_user'@'localhost' 对 test 数据库的 SELECT, INSERT, UPDATE 权限
GRANT SELECT, INSERT, UPDATE ON test.* TO 'app_user'@'localhost';

-- 授予 'remote_user'@'%' 对 test 数据库的所有权限
GRANT ALL PRIVILEGES ON test.* TO 'remote_user'@'%';

授权后,用户需要重新连接才能使部分权限生效,或者执行权限刷新操作。

4.2 查看用户权限

可以使用 SHOW GRANTS 命令查看特定用户的权限。

sql 复制代码
-- 查看 'app_user'@'localhost' 的权限
SHOW GRANTS FOR 'app_user'@'localhost';

4.3 刷新权限(FLUSH PRIVILEGES)

截图中的 flush privileges; 命令,其核心作用是 重新从 mysql 系统库的权限表中加载最新的用户信息和权限设置到内存中。

何时需要执行?

  • 正常情况下 :使用 GRANT、REVOKE、CREATE USER、DROP USER 等专用 SQL 语句修改权限后,MySQL 会自动感知变更并更新内存中的缓存,通常不需要 手动执行 FLUSH PRIVILEGES。
  • 特殊情况下 :如果通过 INSERT、UPDATE、DELETE 等语句直接修改了 mysql.user 等系统权限表 ,那么内存中的权限缓存并不会自动更新。此时,必须执行 FLUSH PRIVILEGES 来强制服务器重新加载权限表,使更改生效。

4.4 回收用户权限(REVOKE)

REVOKE 语句用于回收已授予用户的权限。

回收权限语法:

sql 复制代码
REVOKE 权限列表 ON 库.对象名 FROM '用户名'@'登录位置';

案例:回收权限

sql 复制代码
-- 使用 root 账号
-- 回收 'app_user'@'localhost' 对 test 数据库的所有权限
REVOKE ALL ON test.* FROM 'app_user'@'localhost';

第五章 用户删除与管理

5.1 删除用户(DROP USER)

DROP USER 语句用于移除一个或多个 MySQL 账户。

删除用户语法:

sql 复制代码
DROP USER '用户名'@'主机名';

5.1.1 关于 % 通配符的说明

删除用户时必须指定完整主机名的情况。MySQL 中,'whb' 和 'whb'@'%' 是两个完全不同的账户。

如果执行 DROP USER 'whb';,MySQL 会默认将主机名部分视为 '%',即尝试删除 'whb'@'%' 这个用户。如果该用户不存在,就会报错 ERROR 1396 (HY000)。要删除 'whb'@'localhost',必须精确指定完整名称。

sql 复制代码
-- 错误示例:尝试删除 'whb',但默认匹配的是 'whb'@'%'
DROP USER 'whb';  -- 如果 'whb'@'%' 不存在则报错

-- 正确示例:精确指定主机名
DROP USER 'whb'@'localhost';

第六章 常见问题排查与特殊场景

6.1 MySQL 配置参数 skip-grant-tables 的影响

"MySQL 配置文件选项会让 netstat -nltp 查不到",这个现象与 skip-grant-tables 参数有关。

  • 功能 :当 MySQL 服务器以 --skip-grant-tables 选项启动时,它将不读取权限表,也不实施任何访问控制。这意味着任何用户都可以无密码登录并拥有所有权限,通常用于紧急情况下的密码重置。
  • 副作用 :启用该参数后,MySQL 为了安全考虑,会默认开启 skip-networking ,即禁用所有 TCP/IP 网络连接 。服务器仅允许本地 socket 连接,因此使用 netstat -nltp 命令将无法看到 MySQL 服务监听在 3306 端口上。
  • 解决方法 :在完成紧急操作后,务必从配置文件(如 /etc/my.cnf)中移除或注释掉 skip-grant-tables 这一行,然后重启 MySQL 服务,恢复正常权限检查和网络监听。

第七章 最佳实践总结

  1. 最小权限原则 :仅授予用户完成其工作所必需的最小权限集。避免随意授予 ALL PRIVILEGES。
  2. 限制登录主机 :尽量指定具体的 IP 或主机名,避免使用 '%' 通配符,以减少攻击面。
  3. 使用专用 DDL 语句 :始终使用 CREATE USER、GRANT、REVOKE、DROP USER 等专用语句管理用户和权限,不要直接修改 mysql.user 表。
  4. 关注版本差异 :注意 MySQL 不同版本间的语法差异,尤其是在 8.0 版本中,应使用 ALTER USER 来修改密码。
  5. 谨慎使用维护参数 :skip-grant-tables 仅用于紧急故障恢复,切忌在生产环境中长期开启。
相关推荐
努力努力再努力wz6 小时前
【C++高阶系列】C++20 协程底层原理:函数为什么能暂停?从状态机到 Task,彻底串起挂起、恢复与协程调度
开发语言·c++·c++20·1024程序员节
NoteStream7 小时前
【C语言入门10】指针(1)
1024程序员节
晚风吹北巷7 小时前
Linux复习篇(自用)
linux·运维·服务器·1024程序员节
艾络迅Acceleronix7 小时前
环境监测终端:STM32+EG800Z AT+ 艾络迅平台实战|多传感器采集联动全流程
c语言·stm32·单片机·嵌入式硬件·物联网·1024程序员节
唯鹿7 小时前
AI生成UI代码实践(二)—— Figba 更新月记
ui·ai·figma·1024程序员节·蓝湖
yqj2347 小时前
FunASR安装
1024程序员节
by209997 小时前
Linux 压缩传输、进程查看与权限管理
linux·经验分享·1024程序员节
2601_962885728 小时前
Tushare 前复权回测对不上/不可复现?前复权陷阱与正确做法
1024程序员节
无足鸟ICT8 小时前
【RHCA+】reboot命令(重启)
linux·运维·服务器·1024程序员节