MySQL数据库:用户管理

文章目录

MySQL用户管理从入门到不翻车:别再裸奔用root了!

相信很多刚接触MySQL的同学,从安装到写CRUD,全程一把root钥匙走天下------就像小区所有门都用总控钥匙,想进谁家进谁家,想搬啥搬啥。爽是爽了,但凡手滑敲个drop database,或者被外人摸到账号,那就是删库跑路的大型社死现场。

今天咱们就把MySQL的「用户权限体系」扒明白,从账号查询到host限制,再到权限分配和远程连接踩坑,手把手教你给不同人配不同的"门禁卡",从此告别root裸奔。

一、先翻户口本:MySQL用户存在哪?

MySQL不搞黑箱,所有用户信息都明明白白存在系统库mysql的user表里------这就是MySQL的「户籍登记簿」。

先登进去查一下家底:

sql 复制代码
-- 切换到系统库
use mysql;

-- 查看所有用户的核心信息
select User, Host from user;

真实查询输出示例

你执行后会看到类似这样的结果:

User Host
zhangsan %
mysql.session localhost
mysql.sys localhost
root localhost

逐行解读你的「户口本」

  1. zhangsan | %

    这是你自己创建的自定义账号,格式为 'zhangsan'@'%'。

    • % 是通配符,代表允许从任意IP地址登录。
    • 只要知道密码,全世界任何一台机器都能远程连接你的数据库。
    • ⚠️ 高危预警:这就是典型的"门户大开"配置,学习测试玩玩可以,生产环境绝对禁止。
  2. mysql.session | localhost

    MySQL 内置系统账号,供 MySQL 内部进程通信使用。

    • 不要删除、不要修改密码,否则会导致数据库异常。
  3. mysql.sys | localhost

    系统内置账号,用于 sys 系统库的对象访问。

    • 同样是系统自带账号,别动它就行。
  4. root | localhost

    超级管理员账号,Host 为 localhost 代表只能从本机登录。

    • 外部机器无法直接用 root 远程连接,这个配置是安全的默认配置。

💡 最核心的概念:MySQL里的用户是「用户名 + 主机名 」联合唯一的。

也就是说,'zhangsan'@'localhost'和'zhangsan'@'%'是两个完全不同的账号,密码、权限互不干扰,删的时候也要分开删。

二、host字段全解析:不止localhost,还有这些玩法

host字段用来限制"谁能来连这个数据库",可以精准到一台机器,也可以放宽到一个网段,甚至全开。

1. host取值对照表

host取值 含义 安全等级 适用场景
localhost 本机Socket连接,Linux下走mysql.sock套接字文件,不走TCP网络 ✅ 最高安全 本机服务、本地调试
127.0.0.1 本机TCP回环地址,走3306端口网络连接 ✅ 极高安全 本机通过TCP方式连接
192.168.1.100 只允许这一个固定IP的机器远程连接 ✅ 推荐生产用 指定的开发机、应用服务器
192.168.1.% 允许整个192.168.1.x局域网网段连接,%是通配符 ⚠️ 中等安全 公司内网多台机器访问
% 允许任意IP地址连接,全世界只要知道密码就能连 ❌ 高危 仅学习环境演示,生产严禁
app01.test.com 允许该域名解析出的机器登录 ⚠️ 依赖DNS 极少使用,不推荐

2. 新手最懵:localhost ≠ 127.0.0.1

这是面试高频考点,也是90%的人踩过的坑:

  • 'xxx'@'localhost':走Unix Socket文件,不经过TCP协议,速度更快,但只能本地程序用
  • 'xxx'@'127.0.0.1':走TCP/IP协议,访问3306端口,本质是"远程连接自己"

现象验证:

你创建了用户'test'@'localhost',那么:

bash 复制代码
# ✅ 可以登录(默认走Socket)
mysql -u test -p

# ❌ 报错访问拒绝!因为host不匹配
mysql -h 127.0.0.1 -u test -p

如果希望两种本机方式都能登录,必须创建两个独立账号:

sql 复制代码
create user 'test'@'localhost' identified by 'Test@123456';
create user 'test'@'127.0.0.1' identified by 'Test@123456';

3. 实操:创建不同host的用户

sql 复制代码
-- 1. 只允许本机登录
create user 'local_user'@'localhost' identified by 'Local@123';

-- 2. 只允许192.168.1.20这台开发机登录
create user 'dev_user'@'192.168.1.20' identified by 'Dev@123456';

-- 3. 允许整个192.168.1.x网段登录
create user 'lan_user'@'192.168.1.%' identified by 'Lan@123456';

-- 4. 允许任意IP登录(高危!仅演示)
create user 'danger_user'@'%' identified by 'Danger@123456';

4. 高危账号整改示例

针对上面查到的 'zhangsan'@'%' 这种高危账号,推荐两种整改方案:

方案一:直接删除(不需要了就清掉)

sql 复制代码
drop user 'zhangsan'@'%';

方案二:改成只允许固定IP访问

sql 复制代码
-- 先删除旧的高危账号
drop user 'zhangsan'@'%';

-- 新建只允许指定IP登录的账号
create user 'zhangsan'@'192.168.1.20' identified by 'ZhangSan@123456';

-- 再授权对应权限
grant select on test_db.* to 'zhangsan'@'192.168.1.20';

三、用户账号的"生老病死":增删改全套操作

1. 新建用户:给新人办门禁卡

基础语法:

sql 复制代码
create user '用户名'@'登陆主机/ip' identified by '密码';
🚧 初学者必踩坑:密码太简单报错

如果你设密码像123456,大概率会弹这个错:

复制代码
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

这是MySQL的密码校验插件在干活,嫌你密码太弱。查看当前密码策略:

sql 复制代码
SHOW VARIABLES LIKE 'validate_password%';

学习环境可以调低策略,生产环境强烈建议老老实实设大小写+数字+特殊符号的复杂密码。

🚨 红线警告:别图省事写 @'%'

很多人嫌麻烦直接写create user 'xxx'@'%',相当于你家门锁是个摆设,全世界只要知道密码就能进。学习环境本机用localhost就够了,真需要远程连接也只授权指定IP。

2. 删除用户:销户要带完整信息

想删用户?千万别图省事只写用户名:

sql 复制代码
-- 错误示范!大概率报错
drop user dev_user;
-- ERROR 1396 (HY000): Operation DROP USER failed for 'dev_user'@'%'

为啥报错?因为MySQL默认你没写host就是%,但你创建的是@'localhost'的用户,对不上号当然删不掉。

✅ 正确写法,必须带上host:

sql 复制代码
drop user 'dev_user'@'192.168.1.20';

还是那句话:用户是user+host绑定的,删户也要"精准销户"。

3. 修改密码:换锁操作

分两种场景:自己改自己的,和管理员改别人的。

场景1:自己改自己的密码

登录自己账号后执行:

sql 复制代码
set password = password('新密码');
场景2:root管理员修改指定用户密码
sql 复制代码
-- 兼容旧版本写法
set password for 'dev_user'@'192.168.1.20' = password('Dev@654321');

-- MySQL 8.0+ 官方推荐写法
alter user 'dev_user'@'192.168.1.20' identified by 'Dev@654321';

四、权限才是核心:给你开门但不给你开保险柜

用户创建完只是第一步,真正的灵魂操作是权限分配。MySQL的权限粒度细到"能看哪张表、能不能删数据、能不能建库",完全可以做到"张三只能管mytest库,李四只能管msg库"。

1. 常见权限速览

不用全背,按用途分几类就好:

权限分类 代表权限 能干啥
数据读写 SELECT, INSERT, UPDATE, DELETE 查、增、改、删表数据
结构操作 CREATE, DROP, ALTER, INDEX 建库/建表、删库/删表、改表结构、建索引
视图/存储过程 CREATE VIEW, EXECUTE 创建视图、执行存储过程
服务器管理 CREATE USER, SUPER, SHOW DATABASES 创建用户、超级管理员权限、查看所有库

2. 授权操作:grant 给你发权限

语法模板:

sql 复制代码
grant 权限列表 on 库.对象名 to '用户名'@'登陆位置';
几个关键说明:
  • 权限列表 :多个权限用逗号分隔,比如select,insert,update
  • all [privileges]:代表赋予该对象上的所有权限
  • 范围控制 :
    • *.* = 所有库的所有表(满级权限,别乱给)
    • test_db.* = test_db库下的所有表(最常用)
    • test_db.user_info = 只针对test_db库的user_info表
完整实操示例
  1. root账号先准备测试库表:
sql 复制代码
create database if not exists test_db;
use test_db;

create table if not exists user_info (
    id int primary key auto_increment,
    name varchar(20),
    balance decimal(10,2)
);

insert into user_info(name, balance) values 
('张三', 100.00),
('李四', 200.00),
('王五', 300.00);
  1. 给dev_user开放test_db库的查询权限:
sql 复制代码
grant select on test_db.* to 'dev_user'@'192.168.1.20';
  1. 用dev_user登录验证:
sql 复制代码
-- 能看到test_db库
show databases;

-- 能查询数据
use test_db;
select * from user_info;

-- ❌ 删除报错,因为没给delete权限
delete from user_info where id = 1;
查看用户有哪些权限
sql 复制代码
show grants for 'dev_user'@'192.168.1.20';
🧙 生效咒语:flush privileges

有时候赋完权发现没生效?执行一下这句"刷新咒语":

sql 复制代码
flush privileges;

正常用grant/revoke操作会自动生效,但如果是直接修改mysql.user表的话就必须手动刷新。

3. 回收权限:revoke 把权限收回来

给出去的权限想收回来,用revoke,语法和grant几乎对称:

sql 复制代码
revoke 权限列表 on 库.对象名 from '用户名'@'登陆位置';

比如回收dev_user对test_db的所有权限:

sql 复制代码
revoke all on test_db.* from 'dev_user'@'192.168.1.20';

回收完用户就又变回"白板"了,但账号还在,不会被删除。

五、远程连接终极避坑:90%的人都搞错过IP

这是初学者问得最多的问题:为什么账号建好了,远程还是连不上?大概率是IP搞反了。

1. 灵魂对比:两个IP完全不是一回事

位置 填什么IP 含义
SQL语句里 'dev'@'192.168.1.20' 客户端IP 允许哪台机器来访问;数据库校验:来连接的这台机器是不是这个IP
连接命令 -h 192.168.1.10 服务端IP 客户端要去找哪一台机器上的MySQL服务

2. 生活化例子帮你记牢

  • 数据库服务器A(IP:192.168.1.10)= 银行网点
  • 你的电脑B(IP:192.168.1.20)= 你本人
  1. 'dev'@'192.168.1.20' → 银行规定:只允许你家这个地址的人进来办业务
  2. mysql -h 192.168.1.10 -u dev -p → 你出门:坐车去银行网点的地址办业务

👉 银行地址(-h)和允许来访的客户地址(@ip),是完全不一样的两个东西!

3. 两个最常见的错误

❌ 错误1:@后面写了服务器自己的IP
sql 复制代码
-- 错!@后面应该写客户端IP,不是服务器IP
create user 'dev'@'192.168.1.10' identified by 'Dev@123456';

结果:只有服务器自己能连这个账号,其他机器连都报访问拒绝。

❌ 错误2:-h后面写了客户端自己的IP
bash 复制代码
# 错!-h应该写数据库服务器IP,不是你自己电脑IP
mysql -h 192.168.1.20 -u dev -p

结果:在你自己电脑上找MySQL服务,当然找不到,直接连接超时。

4. 远程连不上?按这个顺序排查

  1. 账号host对不对:确认@后面的IP是你客户端的真实IP
  2. MySQL监听地址 :服务器配置文件my.cnf里,bind-address要设为0.0.0.0(或注释掉),不能只写127.0.0.1
  3. 防火墙:服务器防火墙要放行3306端口
  4. 网络连通性 :客户端先执行ping 服务器IP测试网络通不通,再用telnet 服务器IP 3306测试端口通不通

六、初学者避坑+最佳实践

  1. 最小权限原则

    给用户刚好够用的权限就行。比如开发人员只给select,insert,update,别一上来就grant all,更别随便给*.*权限。

  2. host字段尽量收敛

    能写固定IP绝不写网段,能写网段绝不写%;本机用localhost,远程只授权指定服务器IP。

  3. 删用户一定要带host

    永远别写drop user xxx;,一定要写全'user'@'host',避免删错账号。

  4. 账号定期审计

    隔段时间查一下mysql.user表,看看有没有不用的僵尸账号,特别是host为%的账号,及时清理。

  5. 密码和连接安全

    生产环境禁用弱密码,不要把密码硬编码在代码里;远程连接尽量走内网,不要把3306端口暴露在公网。

七、总结

MySQL用户管理的本质就是权限分离+访问控制:root作为超级管理员管系统,普通用户各司其职,只拿自己该拿的权限,只从允许的机器登录。

回头想想,你从装完MySQL就一直用root,是不是相当于拿着金库钥匙去买早饭?既没必要又危险。从今天起,先执行select User,Host from mysql.user;查一下自己的账号列表,把高危的%账号整改掉,给自己的业务账号单独建个用户,分配对应库的权限------安全这根弦,从初学就绷紧。

相关推荐
冰暮流星1 小时前
sql之is not null运算符
数据库·sql·oracle
冰暮流星1 小时前
sql之is null 运算符
java·数据库·sql
mengge.cloud1 小时前
Redis
运维·服务器·数据库·redis·缓存·云计算
码流子2 小时前
02-易迁信创兼容引擎
大数据·数据库·python
欣栀♡2 小时前
Redis 缓存穿透、击穿、雪崩,背出定义只是及格线
数据库·redis·缓存
杨云龙UP2 小时前
PostgreSQL 四种常见部署模式快速理解:单实例、流复制、repmgr、Patroni
linux·运维·数据库·postgresql·流复制·高可用ha
l1t2 小时前
DeepSeek总结的PostgreSQL 19回退会一直继续,直到士气好转
数据库·postgresql
ao-weilai2 小时前
MySQL数据库:C语言连接MySQL教程
c语言·数据库·mysql
盛世宏博智慧档案2 小时前
档案库房温湿度采集数据存储方案:时序数据库选型与存储优化
数据库·时序数据库