资讯动态

MySQL用户权限管理实战:从创建用户到最小权限授权

发布时间:2026/10/21 15:41:27 来源:尧图企业网站定制
作为后端工程师你迟早要跟 MySQL 打交道。我刚工作那会儿环境不太规范经常是项目需要连库就直接给 root 权限有的甚至一个业务连生产库、测试库都全用 super 账号。后来线上出了一次事故发现问题出在一个开发同学误操作把一张核心业务表的数据清掉了而当时那个连接用的正是最高权限账号。那之后我才真正意识到创建用户并授权这件事看起来是几条 SQL 命令的事但背后是一整套访问控制和安全设计思路。这篇文章不打算只给你扔几条 SQL 让你照着抄。我会把“为什么这么授权”“授权后怎么验证”“遇到问题怎么排查”这套东西串起来讲。即使你是个刚接触 MySQL 的新手看完也能自己动手建立一个比较规范、安全的用户体系。对于有经验的朋友里面也有一部分是我实际踩坑总结出来的细节可以当个查漏补缺的资料用。1. 权限设计思路先想清楚再动手写命令1.1 一个账号走天下的隐患很多人在给应用配数据库时天然觉得“反正公司内网权限无所谓”。这就是最大的误区。数据库不像代码仓库代码出问题可以被 Code Review 拦住而数据库权限给错了一个 DELETE 或者 DROP 就可能是不可逆的。举个例子。之前有朋友的公司内部开发、测试、生产环境共用一套 MySQL 实例所有环境用的都是同一个账号。测试环境的数据脚本刷掉了生产库的一批客户订单最后只能靠 binlog 花了两天时间慢慢恢复。这个事故的根源就是权限没有隔离那个账号对生产库有完整操作权限而测试脚本又误连了生产库。权限设计的第一原则是“最小权限原则”只给用户完成任务所必需的最小权限不要多给。放到 MySQL 里就是一个业务应用账号只赋给它对应业务库的增删改查SELECT/INSERT/UPDATE/DELETE权限不要给 DROP、ALTER 这类结构变更权限更不要给 SUPER、GRANT 这类管理权限。运维人员操作生产环境时用一个独立的账号权限按需分配日常禁止使用 root。不同环境如开发、测试、生产之间要么用独立的 MySQL 实例要么至少用独立的库和独立的账号互不影响。这个习惯如果能养成比你用任何安全审计工具都管用。1.2 MySQL 用户与权限的基本模型MySQL 的权限体系一句话说就是用户User 主机Host 权限Privilege三者绑定。用户看起来像用户名主机其中主机部分限定这个用户从哪台机器连过来有效。例如applocalhost表示只有本机连接能生效app192.168.1.%表示来自 192.168.1.x 网段的连接能生效app%则表示不限制来源 IP。为什么要区分主机这是 MySQL 安全模型里非常实用的一个设计。比如某电商项目我单独给服务器网段ecommerce_app10.10.10.%开了数据库访问权限这时候哪怕应用账号的密码被人拿到了攻击者也只能在内部网段的机器上才能用这个账号登录直接把攻击面切掉了一大块。权限Privilege则控制能做什么例如 SELECT、INSERT、UPDATE、DELETE、CREATE、DROP、ALTER、INDEX、RELOAD、SHUTDOWN、SUPER 等等。权限又分为几个层级全局权限作用于整个 MySQL 实例、数据库权限作用于某个库、表权限作用于某张表、列权限作用于某列、存储过程/函数权限等。授权的时候权限范围越精确越好。很多人一上来就GRANT ALL PRIVILEGES ON *.* TO ...这就等于把整个实例的钥匙全部交出没有隔离效果。重要提醒权限层级是“累加”的。如果某个用户既有全局的 SELECT 权限又有对某库的 ALL 权限那最终生效的就是两者并集。设计权限时要特别注意别通过这种累加方式不小心扩大权限。1.3 授权工具选型命令行最直接管理 MySQL 用户和权限的方式无非那么几种命令行mysql 客户端、可视化工具如部分图形化数据库客户端、以及各种配置管理工具。我们的核心操作场景还是命令行原因有几个命令行直接对应 MySQL 原生的 SQL 语句不受图形工具版本和功能限制。在服务器上操作时命令行是最普遍、最可靠的方式。脚本化、自动化授权时SQL 语句本身可以直接复用。用命令行操作之前你需要能连上 MySQL。通常是在安装 MySQL 的服务器上执行mysql -uroot -p输入 root 密码后进入 MySQL 命令行环境。如果 root 也无法登录那属于另一类问题我后面第 5 节专门讲。2. 创建用户与权限管理核心实操2.1 如何创建一个用户先看一个最基础的例子CREATE USER demo_userlocalhost IDENTIFIED BY MyPassword123;这条语句创建了一个用户demo_user只允许从本机连接密码是MyPassword123。此时的demo_user默认没有任何权限它只能登录不能操作任何数据库甚至看不到任何库的表数据但能看到 MySQL 元数据。创建用户的常见写法-- 指定密码5.7 及之前最常见的写法 CREATE USER app01192.168.10.% IDENTIFIED BY AppPass2024; -- 不限制来源主机开发环境常用生产环境慎用 CREATE USER dev01% IDENTIFIED BY DevPass2024; -- MySQL 8.0 默认加密方式就是 caching_sha2_password直接创建即可 CREATE USER app0210.0.0.% IDENTIFIED BY AppPass2024;几个容易忽略的细节用户名与主机是组合主键。applocalhost和app%是两个完全不同的账号可以共存。如果两者都创建了本地登录会优先匹配applocalhost。密码要符合复杂度要求。MySQL 从 5.7 开始有validate_password插件默认会要求密码长度和字符组合。如果密码太简单会收到报错例如ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。这个问题处理起来很简单把密码设定得复杂一些比如大小写字母、数字、特殊字符组合长度超过 8 位。如果你是在内部临时测试环境想降低密码策略强度可以这样调整SET GLOBAL validate_password.policy LOW;注意这是 MySQL 8.0 的写法5.7 里的写法是SET GLOBAL validate_password_policy LOW;两个版本不一样别搞混。2.2 用户与主机匹配机制前面提到userhost是一个组合概念这里再深入展开一下。MySQL 在用户登录时会从 mysql.user 表里按匹配规则找到合适的记录。匹配规则按主机部分精确度排序越精确的优先匹配。比如 mysql.user 表里有这两条记录rootlocalhost root%本机连接 root 时MySQL 会优先用rootlocalhost那条记录来校验密码。即使两条记录的密码不一样也不会混淆。这个机制在工作中的一个典型应用场景是你想在服务器本机用 root 管理数据库又不想让 root 密码被远程尝试爆破就可以只保留rootlocalhost删除root%甚至不创建远程 root。然后单独为远程管理创建一个受限账号只允许从你的办公网段连接。查看当前所有用户SELECT user, host, plugin FROM mysql.user;输出结果里能看到用户名、允许来源主机、认证插件。这个命令在你排查“明明创建了用户为什么连不上”时很有用。2.3 修改用户与安全管理用户创建之后可能会遇到需要修改密码或者暂时锁定账号的情况。常用操作如下-- 修改用户密码MySQL 5.7 及以前写法 SET PASSWORD FOR app01192.168.10.% PASSWORD(NewPass2024); -- 修改用户密码MySQL 8.0 推荐写法 ALTER USER app01192.168.10.% IDENTIFIED BY NewPass2024; -- 锁定账号不让登录 ALTER USER app01192.168.10.% ACCOUNT LOCK; -- 解锁账号 ALTER USER app01192.168.10.% ACCOUNT UNLOCK;我建议把密码修改和账号锁定/解锁作为日常运维的标准操作。比如某个同事离职又掌握着数据库账号密码第一时间不是删账号而是先锁定账号确认没有影响后再删除。这样可进可退避免“删了又需要找回”的尴尬。2.4 重名用户与授权时的优先级坑因为userhost是组合概念所以授权时最好也带上主机名不要只写用户名。例如GRANT SELECT ON mydb.* TO demo_userlocalhost;如果你写GRANT SELECT ON mydb.* TO demo_user;MySQL 会自动把它转换成GRANT SELECT ON mydb.* TO demo_user%;。如果你原本只有demo_userlocalhost而授权给了demo_user%那你实际上创建了一个新的用户记录而不是给原来的账号授权。这个操作就很容易埋下隐患你以为是同一个账号实际上已经变成了两个账号。我处理过的一个真实案例某项目要求给应用账号增加权限操作的同学执行授权命令时没注意主机部分导致 MySQL 自动创建了一个app_user%空密码账号因为原来的app_userlocalhost有密码而新创建的app_user%没有设密码。结果这台机器直接暴露在公网扫描之下差点被拖库。所以每次创建用户和授权一定把必须写主机部分当作习惯别偷懒。3. 授权命令的细节与权限粒度控制3.1 授权的基本语法授权的核心语句是GRANT。它可以把某个层级、某些操作权限授予用户。基本语法GRANT 权限类型 ON 权限级别 TO 用户主机 [WITH GRANT OPTION];常用权限类型包括数据操作类SELECT、INSERT、UPDATE、DELETE结构操作类CREATE、ALTER、DROP、INDEX、CREATE VIEW管理类SUPER、RELOAD、SHUTDOWN、PROCESS、GRANT OPTION特殊ALL PRIVILEGES除了 GRANT OPTION 本身之外的所有权限权限级别包括*.*所有库、所有表全局db_name.*指定库下的所有对象数据库级db_name.table_name指定表表级db_name.proc_name指定存储过程举几个实际的授权例子-- 给应用账号赋某库的全部数据读写权限不包括结构变更 GRANT SELECT, INSERT, UPDATE, DELETE ON shopdb.* TO shop_app10.0.0.%; -- 给某库赋结构变更权限一般给开发者在测试库用 GRANT CREATE, ALTER, DROP, INDEX, CREATE VIEW ON devdb.* TO dev_worker192.168.1.%; -- 只读账号只给查询权限 GRANT SELECT ON reportdb.* TO reader192.168.1.%; -- 全局只读的账号比如给监控系统用 GRANT SELECT, SHOW DATABASES, PROCESS ON *.* TO monitor192.168.1.%;注意GRANT授权后不需要再执行FLUSH PRIVILEGES。很多人被老教程带偏以为必须刷新才能生效实际上直接修改系统表如 INSERT INTO mysql.user才需要刷新用 GRANT 语句授权时 MySQL 已经自动刷新了权限缓存。3.2 WITH GRANT OPTION 要慎用WITH GRANT OPTION表示允许这个用户把自己拥有的权限再转授给其他用户。这个权限非常危险因为授权是可以传递的A 有了 GRANT OPTION他就可以把权限给 BB 又可以给 C权利被一层层放大最后你很难追踪到底谁有哪些权限。一般情况下应用账号绝对不要加WITH GRANT OPTION。即使是 DBA 团队内部分权也要谨慎使用并配合清晰的权限登记流程。如果你需要撤销用户的 GRANT OPTION可以用REVOKE GRANT OPTION ON *.* FROM someuserlocalhost;3.3 授权原则最小权限、按需分配实际操作中我建议按角色把授权拆成几档只读账号只有 SELECT。适合报表、数据分析、数据抽取。读写账号SELECT、INSERT、UPDATE、DELETE。适合业务应用后端。结构变更账号通常是读写 CREATE、ALTER、DROP、INDEX。适合开发和测试环境生产环境尽量避免。管理账号全库相关权限一般只给 DBA 使用。超级管理账号root 或 ALL PRIVILEGES GRANT OPTION仅用于初始化和灾难恢复。这样拆分后即使某个账号泄露了攻击者能做的也只是对应权限范围内的事能把损失控制在一定范围内。举一个实际的财务系统授权案例-- 财务只读账号给审计查询用 CREATE USER fin_audit192.168.10.% IDENTIFIED BY FinAudit2024; GRANT SELECT ON finance.* TO fin_audit192.168.10.%; -- 财务写入账号给业务系统用 CREATE USER fin_app10.10.20.% IDENTIFIED BY FinApp2024; GRANT SELECT, INSERT, UPDATE, DELETE ON finance.* TO fin_app10.10.20.%; -- 财务表结构变更账号给开发在预发环境用 CREATE USER fin_dev192.168.10.% IDENTIFIED BY FinDev2024; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX ON finance.* TO fin_dev192.168.10.%;注意各账号来源主机不一样权限也不一样职责更不一样。这比所有环境一个账号一把梭要清楚得多。3.4 查看、回收与删除权限权限给出去容易收回来反而更需要留意。查看某个用户的权限SHOW GRANTS FOR shop_app10.0.0.%;也可以查更细的信息SELECT * FROM mysql.tables_priv WHERE user shop_app\G SELECT * FROM mysql.columns_priv WHERE user shop_app\G回收权限用REVOKE语法和GRANT基本对应-- 回收某用户的删除权限 REVOKE DELETE ON shopdb.* FROM shop_app10.0.0.%; -- 回收某用户全部权限 REVOKE ALL PRIVILEGES ON *.* FROM dev01%; -- 回收后如果不需要该用户了直接删除 DROP USER dev01%;经验之谈回收 DELETE 权限前先确认应用里的删除功能是否真的走的是该账号。我遇到过开发同学把账号给到了另一个项目共用的情况回收权限之后那个应用直接开始报错排查半天才发现账号被多个项目复用。所以维护账号时做好“账号-项目”对应关系的登记非常有必要。DROP USER会级联清理该用户的所有授权不需要先REVOKE再DROP这点跟很多人想的不一样。4. 实战场景配置从零开始搭建一套用户权限4.1 场景背景与方案设计假设我们手上有一个新项目叫“某电商业务系统”后端使用一个 MySQL 8.0 实例。项目分三个环境开发dev、测试test、生产prod。按照前面说的最小权限原则我们需要三套账号分别对应三个环境并且每个环境的账号只访问自己对应的库。库规划如下dev 环境库里叫shop_devtest 环境库里叫shop_testprod 环境库里叫shop_prod账号规划如下开发环境shop_dev192.168.1.%可读写 表结构变更权限测试环境shop_test192.168.1.%可读写 表结构变更权限测试环境常需要重建表结构生产环境shop_prod10.10.10.%只给 SELECT、INSERT、UPDATE、DELETE不授结构变更权限4.2 完整实操流程先创建三个数据库CREATE DATABASE IF NOT EXISTS shop_dev DEFAULT CHARACTER SET utf8mb4; CREATE DATABASE IF NOT EXISTS shop_test DEFAULT CHARACTER SET utf8mb4; CREATE DATABASE IF NOT EXISTS shop_prod DEFAULT CHARACTER SET utf8mb4;然后按规划创建用户并授权-- 开发环境账号 CREATE USER shop_dev192.168.1.% IDENTIFIED BY ShopDev2024; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, CREATE VIEW ON shop_dev.* TO shop_dev192.168.1.%; -- 测试环境账号 CREATE USER shop_test192.168.1.% IDENTIFIED BY ShopTest2024; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, CREATE VIEW ON shop_test.* TO shop_test192.168.1.%; -- 生产环境应用账号 CREATE USER shop_prod10.10.10.% IDENTIFIED BY ShopProd#2024; GRANT SELECT, INSERT, UPDATE, DELETE ON shop_prod.* TO shop_prod10.10.10.%; -- 生产环境只读账号给运营和 BI 用 CREATE USER shop_readonly10.10.20.% IDENTIFIED BY ShopRead#2024; GRANT SELECT ON shop_prod.* TO shop_readonly10.10.20.%;执行完所有授权后验证SHOW GRANTS FOR shop_prod10.10.10.%;预期输出里应该只有 SELECT、INSERT、UPDATE、DELETE 四个权限没有 CREATE、DROP、ALTER。4.3 验证授权结果与常见误区很多人执行完成授权后不做验证等到业务上线了才发现“权限不足”或者“权限过大”。正确的操作是在授权完成后用对应的用户登录到 MySQL实际执行几条代表性语句。例如验证生产只读账号mysql -ushop_readonly -p -h10.10.20.5然后尝试SELECT * FROM shop_prod.orders LIMIT 1;再尝试写入INSERT INTO shop_prod.orders (order_no) VALUES (TEST);此时应该收到权限不足的错误例如ERROR 1142 (42000): INSERT command denied to user ...。这恰恰说明权限隔离生效了。另一个常见误区是使用ON *.*来授权业务账号导致业务账号对所有库都有操作权限。一旦某个库数据泄露牵连的就不仅是一个项目。4.4 授权后如何优雅调整项目迭代过程中权限调整是常态。一个常见的新增场景生产环境需要临时给某个 DBA 账号开放一段时间的数据修复权限用于处理脏数据。做法是明确窗口期-- 赋予临时权限 GRANT UPDATE, DELETE ON shop_prod.orders TO dba_temp10.10.10.%; -- 执行完数据修复后立即回收 REVOKE UPDATE, DELETE ON shop_prod.orders FROM dba_temp10.10.10.%;甚至可以配合定时提醒写一个小脚本到期自动执行REVOKE。权限这个东西越早回收越好千万别留着回头再收。5. 常见报错与排查技巧速查5.1 报错现象、原因与解决方案汇总这里整理一份我在实际工作中高频遇到的 MySQL 用户与权限相关报错附上排查思路。我们用一个表格来整理方便你之后排查时快速对照。报错信息常见原因解决方案ERROR 1045 (28000): Access denied for user xxxyyy (using password: YES)用户名或密码错误或用户不存在于该来源主机检查用户名、密码、来源 IP 是否匹配确认 mysql.user 表里的 host 记录ERROR 1045 ... (using password: NO)没提供密码但用户设置了密码补充 -p 参数并输入密码ERROR 1410 (42000): You are not allowed to create a user with GRANT当前账号没有创建用户的权限用 root 或具有 GRANT OPTION 的账号执行ERROR 1133 (42000): Cant find any matching row in the user table用户不存在或 host 匹配不到先用 SELECT user,host FROM mysql.user 查一下准确的主机部分ERROR 1396 (HY000): Operation DROP USER failed for xxxyyy用户不存在或存在xxx%而你删的是xxxlocalhost确认用户全名使用DROP USER xxx%或xxxlocalhostERROR 1819 (HY000): Your password does not satisfy the current policy requirements密码复杂度不够设置更复杂的密码或调整 validate_password 策略ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation当前账号缺少 SUPER 权限操作需要管理权限用管理员账号授权或执行应用中尽量避免使用 SUPER 权限账号ERROR 2003 (HY000): Cant connect to MySQL server on x.x.x.x网络不通或 MySQL 未启动也可能是端口没放通先 ping 目标 IP再用 telnet/数据库客户端检查端口确认 bind-address 配置5.2 记住密码丢失时的脱困方案这里要特别说明一下 root 密码忘记的场景。因为用户管理本身就是基于 root 的如果 root 都进不去整个授权工作就无从谈起。我有一次在部署一个新环境时因为安装时设置的 root 密码被同事误改了导致后期所有授权操作全被卡住最后只能通过跳过权限表临时登录来处理。处理过程如下Linux 环境下常见做法停止 MySQL 服务sudo systemctl stop mysqld在配置文件一般是/etc/my.cnf或/etc/mysql/my.cnf的[mysqld]段添加一行跳过授权表启动skip-grant-tables启动 MySQL 服务sudo systemctl start mysqld登录并重置密码mysql -uroot进入 MySQL 后FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY NewRootPass2024;删除配置里的skip-grant-tables这一行重启 MySQL。这个过程我不建议日常使用因为跳过授权表启动时MySQL 不校验任何权限非常危险。一定要保证该操作是在本机离线环境下进行并且完成密码重置后立即去掉该配置。重要提醒永远不要在生产环境开着skip-grant-tables运行。曾经有管理员为了图省事一直带着这个参数跑测试库结果被内网扫描器扫到数据库被改了一塌糊涂。这个参数只适合应急不能当常规配置来用。5.3 授权不生效的几种隐蔽原因权限排查中最头疼的一类情况是明明执行了 GRANT用SHOW GRANTS也查到了权限但应用连上去执行 SQL 还是报权限不足。被这种问题折磨过的人不在少数。就我的经验来讲根源通常是以下几个你连的库不是被授权的那个库。比如授权的是shop_dev.*但应用在连接串里写的是shop_prod。这种低级错误在测试环境最常见。匹配到了另一个同名用户。之前说过applocalhost和app%是两个账号。如果本地连接时匹配到了applocalhost但授权只给了app%那本地连接并不具有这些权限。权限层级之间的冲突。MySQL 的权限是累加的但有些操作会同时检查不同层级的权限。比如对一个存储过程的执行既有 EXECUTE 权限要求也可能有表权限要求。只授了 EXECUTE 但是没授表上的 SELECT存储过程依然可能报权限不足。连接池缓存了旧连接。这个最坑。应用因为连接池长时间缓存了旧连接即使你在数据库侧改了权限已建立的连接不会被强制中断。有些连接池默认 timeout 很久权限变更后迟迟不生效。解决办法是重启应用或清理连接池。排查这类问题时我一般会按这个路径走SHOW PROCESSLIST;看看应用当前连接用的哪个账号、哪个主机。用该账号手动登录 MySQL执行SELECT CURRENT_USER();。对比CURRENT_USER()和SHOW GRANTS确认实际生效的账号和权限情况。最后再检查连接串是不是连到了正确库。这套流程基本能覆盖绝大多数“授权不生效”的场景。5.4 MySQL 8.0 与 5.7 的差异注意点如果你几年前习惯了 MySQL 5.7 的授权写法切到 MySQL 8.0 后会踩到一些细微的坑。最典型的差异是密码认证插件MySQL 5.7 默认使用mysql_native_password很多旧客户端和旧驱动能直接适配。MySQL 8.0 默认使用caching_sha2_password安全性更高但一些旧的数据库连接驱动特别是老版本的一些编程语言驱动不支持会报出奇怪的认证错误比如Authentication plugin caching_sha2_password cannot be loaded。处理方式有两种第一种升级应用侧的连接驱动到支持新认证插件的版本。这是最推荐的长期方案。第二种如果短期内没法升级驱动可以把用户改回旧认证插件ALTER USER some_app10.0.0.% IDENTIFIED WITH mysql_native_password BY SomePass2024;注意这属于兼容性妥协等驱动升级完成后建议改回更安全的认证方式。还有一个差异是PASSWORD()函数的移除。在 MySQL 8.0 里PASSWORD(xxx)这个函数已经不再使用了直接给IDENTIFIED BY 明文密码即可。如果在 8.0 里试图使用旧语法可能直接报语法错误。5.5 我的避坑建议与实用习惯一些实操中沉淀下来的习惯这里一并分享给各位所有账号用统一的命名规范。格式建议是项目_用途_环境比如ecom_app_prod、ecom_readonly_dev。这样 DBA 看到账号就知道是给谁用的。没有规范的账号体系不出三个月就乱成一锅粥。授权记录留痕。至少在一个共享文档或者 wiki 里登记每个账号的用途、权限变更历史、负责人、创建时间。权限变更频繁的时候这个记录能帮你快速定位“谁在什么时候改了什么权限”。不要用数据库账号当业务密码存储容器。有些同学喜欢把连接串里的密码明文写在工程配置里然后提交到代码仓库。这种做法相当危险一旦仓库泄露数据库就暴露了。建议用配置中心或环境变量管理连接字符串并限制仓库的访问权限。定期清理僵尸账号。半年一次查mysql.user表凡是用途不明确的账号统一冻结、确认、删除。曾经接手过一个项目数据库里有十几个账号没人说得清哪个是哪个项目的排查问题事倍功半。为每一个应用单独建账号不共用。即使两个应用访问同一个库也建两个账号方便定位问题的源头也方便独立回收权限。6. 快速掌握常用命令速查清单最后放一个精简命令清单便于以后快速查阅。创建与删除用户CREATE USER userhost IDENTIFIED BY password; DROP USER userhost; ALTER USER userhost IDENTIFIED BY new_password; ALTER USER userhost ACCOUNT LOCK; ALTER USER userhost ACCOUNT UNLOCK;授权与回收GRANT SELECT, INSERT, UPDATE, DELETE ON dbname.* TO userhost; GRANT ALL PRIVILEGES ON dbname.* TO userhost; GRANT SELECT ON *.* TO userhost; REVOKE DELETE ON dbname.* FROM userhost; REVOKE ALL PRIVILEGES ON *.* FROM userhost;查看权限与用户SHOW GRANTS FOR userhost; SELECT user, host, plugin FROM mysql.user;刷新权限FLUSH PRIVILEGES;这个命令只有在修改系统表后需要执行用 GRANT/REVOKE 语句操作时不是必需的。我自己在实际维护 MySQL 时最大的体会是用户的权限设计不是一次性的任务而是一个持续演进的过程。项目从初期到成熟期数据库账号体系会经历大量变更如果一开始就建立了清晰的规范和登记习惯后面所有操作都更顺畅也更少出乱子。希望这篇文章能帮你把这一步走扎实省下后续很多不必要的麻烦。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑