摘要 :本文手把手教你创建 MySQL 只读账号,遵循"最小权限原则"保障数据安全。内容包括:准备工作、使用
CREATE USER创建只读用户、用GRANT SELECT授予查询权限、刷新权限、验证只读账号是否生效,以及多数据库管理、账号回收与生产环境最佳实践建议。核心就两条 SQL:CREATE USER创建用户,GRANT SELECT授予查询权限。
创建MySQL只读账号:从零到一的权限管控实践
在数据库管理中,**"最小权限原则"**是保障数据安全的核心法则。无论是给开发人员排查问题、给数据分析师跑报表,还是给BI工具对接数据源,直接把 root 账号或者高权限账号给出去都是极其危险的行为。
一旦误操作执行了 DELETE 或 DROP,后果往往不堪设想。因此,创建一个**只有查询权限(只读)**的 MySQL 账号,是每一位开发者和运维人员的必备技能。
本文将从零开始,手把手带你创建一个安全、规范的 MySQL 只读账号。
1. 准备工作
在开始之前,你需要准备以下环境:
- 一台安装了 MySQL 的服务器(本文适用于 MySQL 5.7 及 8.0+ 版本)。
- 一个具有授权权限的账号 (通常是
root账号,或者拥有CREATE USER和GRANT OPTION权限的账号)。 - 明确只读账号的用途 :
- 需要访问哪个数据库?(例如:
sales_db) - 允许从哪个 IP 地址连接?(例如:只允许
192.168.1.%网段,或者应用服务器10.0.0.12)
- 需要访问哪个数据库?(例如:
1. 操作步骤
第一步:使用 root 账号登录 MySQL
打开终端,使用 root 账号连接到 MySQL 服务器:
bash
mysql -u root -p
输入 root 密码后,看到 mysql> 提示符,说明登录成功。
第二步:创建只读用户
我们使用 CREATE USER 语句来创建一个新用户。这里以创建一个名为 readonly_user 的用户为例。
基础命令:
sql
CREATE USER 'readonly_user'@'192.168.1.%'
IDENTIFIED BY 'StrongPass#2026';
** 参数详解:**
'readonly_user'@'192.168.1.%':这是 MySQL 的用户标识,由"用户名"和"允许连接的 Host"组成。- 如果你希望该用户只能从本机连接,把 Host 改为
'localhost'。 - 如果你希望指定某台服务器(如
10.0.0.12)连接,改为'readonly_user'@'10.0.0.12'。 - 生产环境强烈不建议使用
'%'(代表所有 IP 均可连接),这会带来极大的暴力破解风险。
- 如果你希望该用户只能从本机连接,把 Host 改为
IDENTIFIED BY 'StrongPass#2026':设置登录密码。请务必使用包含大小写字母、数字和特殊字符的强密码。
第三步:授予只读(SELECT)权限
只读账号的核心就是只给 SELECT 权限,不给 INSERT、UPDATE、DELETE 或 DROP。
假设我们只允许该用户查询 sales_db 这个数据库:
sql
GRANT SELECT ON sales_db.* TO 'readonly_user'@'192.168.1.%';
** 参数详解:**
SELECT:赋予查询权限。sales_db.*:表示sales_db数据库下的所有表 。*是通配符,这样即使以后该库新增了表,只读用户也能直接查询,无需重新授权。TO 'readonly_user'@'192.168.1.%':指定把权限授给哪个用户。
(可选) 如果你还需要让该用户查看视图的定义(即执行 SHOW CREATE VIEW),需要额外加上 SHOW VIEW 权限:
sql
GRANT SELECT, SHOW VIEW ON sales_db.* TO 'readonly_user'@'192.168.1.%';
第四步:刷新权限(让配置生效)
虽然在 MySQL 8.0 之后,很多 GRANT 操作会自动加载,但为了兼容所有版本并确保万无一失,建议手动刷新一下权限表:
sql
FLUSH PRIVILEGES;
至此,只读账号已经创建并授权完毕!
2. 验证只读账号是否生效
不要以为执行完命令就万事大吉了,一定要亲自验证。
2.1. 查看授权结果
在 root 账号下,执行以下命令查看该用户的权限:
sql
SHOW GRANTS FOR 'readonly_user'@'192.168.1.%';
如果输出结果中只包含 USAGE ON *.* 和 SELECT ON sales_db.*,说明授权正确。
2.2. 实际连接测试
打开一个新的终端窗口,使用只读账号登录:
bash
mysql -u readonly_user -p -h 192.168.1.100 sales_db
尝试执行查询:
sql
SELECT * FROM orders LIMIT 1;
✅ 预期结果:成功返回数据。
尝试执行写入或删除:
sql
INSERT INTO orders (id) VALUES (1);
-- 或者
DELETE FROM orders WHERE id=1;
❌ 预期结果:报错!
ERROR 1142 (42000): INSERT command denied to user 'readonly_user'...
看到这个报错,说明你的只读权限已经完美生效了。
3. 进阶:如何管理多个数据库?
如果该用户需要同时查询 sales_db 和 report_db 两个库,只需要再执行一次 GRANT 命令即可:
sql
GRANT SELECT ON report_db.* TO 'readonly_user'@'192.168.1.%';
FLUSH PRIVILEGES;
4. 账号回收与删除(备用知识)
如果员工离职或者项目下线,记得及时回收权限或删除账号。
收回某个库的 SELECT 权限:
sql
REVOKE SELECT ON sales_db.* FROM 'readonly_user'@'192.168.1.%';
彻底删除该账号:
sql
DROP USER 'readonly_user'@'192.168.1.%';
5. 生产环境最佳实践建议
- Host 尽量收窄 :永远不要对只读账号使用
'%',按应用服务器或办公网 IP 段精确授权。 - 一人一账号:如果是多人使用,尽量每人创建一个独立账号。这样一旦出问题,审计日志能直接定位到具体的人。
- 查报表走从库 :如果有主从架构,只读账号的
host应该指向**从库(Slave)**的 IP。这样即使跑大型SELECT查询,也不会拖慢主库的写入业务。 - MySQL 8.0+ 推荐使用角色(Role) :如果你管理着几十上百个只读账号,可以创建一个
'readonly_role'角色并赋予SELECT权限,然后把角色赋给用户,管理起来更加优雅。
总结
创建 MySQL 只读账号其实非常简单,核心就是两条 SQL:
CREATE USER创建用户。GRANT SELECT授予查询权限。
但背后的安全理念却至关重要。通过合理的权限隔离,你不仅能防止误删数据的悲剧,还能让数据库架构更加清晰、安全。
现在,打开你的终端,为你的项目创建一个只读账号吧!