云计算百科
云计算领域专业知识百科平台

MySQL基础篇之视图与用户管理

 一、视图(View)

1.1 什么是视图

视图是一种虚拟表,它本身不存储数据,只存储一条预定义的 SELECT 查询语句。当你查询视图时,MySQL 会动态执行这条 SELECT 语句,把结果当作一张表返回给你。

注意:这里的"视图"和事务 MVCC 中的"ReadView(读视图)"完全是两个概念,没有任何关系。

  • 本章的视图(View):数据库对象,是 SELECT 语句的别名/封装,是持久化的虚拟表。
  • 事务中的 ReadView:内存中的数据结构,用于 MVCC 判断数据版本可见性,事务结束就销毁。

1.2 创建视图

语法

CREATE VIEW 视图名 AS SELECT语句;

示例

CREATE VIEW myview AS
SELECT EMP.ename, DEPT.deptno, DEPT.dname
FROM EMP
INNER JOIN DEPT ON EMP.deptno = DEPT.deptno;

创建后,myview 就可以像普通表一样查询:

SELECT * FROM myview;

这等价于直接执行那条复杂的多表连接查询。

1.3 视图的本质:不存数据,只存定义

视图的核心特点是只存储 SQL 定义,不存储查询结果数据。

  • 视图的数据来自基表(底层的真实表),是查询时动态计算出来的;
  • 基表数据变化时,视图的查询结果也会随之变化;
  • 对视图执行 DML(INSERT/UPDATE/DELETE),本质上是在修改基表的数据——因为视图本身没有数据可改。

视图不存储数据,对视图的修改最终落到基表上;基表变了,查询视图的结果自然也变了。 但不是所有视图都能修改,见 1.5 节。

1.4 视图的优点与用途

优点说明
简化复杂查询 把多表连接、子查询等复杂 SQL 封装成视图,使用时只需 SELECT * FROM 视图名
权限控制 只给用户开放视图的查询权限,不开放基表,从而隐藏敏感字段(比如工资、身份证号)
数据独立性 基表结构变化时,可以通过修改视图定义保持上层应用不变,实现逻辑数据独立性
逻辑清晰 给复杂查询起一个有意义的名字,提升 SQL 可读性和可维护性

1.5 可更新视图与不可更新视图

不是所有视图都能执行 INSERT/UPDATE/DELETE。

可更新视图必须同时满足
  • 没有聚合函数(SUM、COUNT、MAX、MIN、AVG 等)
  • 没有 DISTINCT
  • 没有 GROUP BY / HAVING
  • 没有 UNION / UNION ALL
  • SELECT 列表和 WHERE 子句中没有子查询
  • 基于单表(多表连接的视图一般不可更新)
  • 没有引用其他不可更新的视图
  • 示例

    — 可更新视图(基于单表,无聚合)
    CREATE VIEW v_emp10 AS
    SELECT empno, ename, sal FROM EMP WHERE deptno = 10;

    — 可以修改(本质修改基表)
    UPDATE v_emp10 SET sal = sal + 100 WHERE empno = 7782;

    — 不可更新视图(有聚合 + GROUP BY)
    CREATE VIEW v_dept_avg AS
    SELECT deptno, AVG(sal) AS avg_sal FROM EMP GROUP BY deptno;
    — 对 v_dept_avg 执行 UPDATE 会报错

    1.6 视图的其他操作

    — 查看所有视图(视图也是表,show tables 能看到)
    SHOW TABLES;

    — 查看视图定义
    SHOW CREATE VIEW 视图名;

    — 修改视图定义
    CREATE OR REPLACE VIEW 视图名 AS 新的SELECT语句;
    — 或
    ALTER VIEW 视图名 AS 新的SELECT语句;

    — 删除视图
    DROP VIEW 视图名;

    — 同时删除多个视图
    DROP VIEW 视图1, 视图2;


    二、用户管理

    2.1 用户数据存储在哪里

    MySQL 是网络数据库服务,登录需要账号密码。用户信息本身也是数据,存储在 MySQL 自带的系统库 mysql 中。

    — 切换到 mysql 系统库
    USE mysql;

    — 查看所有表
    SHOW TABLES;

    其中最核心的是 user 表,存储所有用户的账号、密码、全局权限等信息。

    — 查看表结构
    DESC user;

    — 查看所有用户(垂直显示更清晰)
    SELECT * FROM user \\G;

    2.2 MySQL 用户的唯一标识:'用户名'@'主机'

    MySQL 的用户不是只由用户名唯一标识,而是由 '用户名'@'主机名' 共同唯一标识。

    'root'@'localhost' 和 'root'@'%' 是两个完全不同的用户!

    它们可以有不同的密码、不同的权限。登录时,MySQL 根据你连接的来源 IP,在 user 表中找最精确匹配的那一条记录(host 越具体优先级越高),而不是模糊匹配。

    Host 字段的常见形式
    Host 值含义
    localhost 仅允许本地连接(Unix socket 或本地回环 TCP)
    192.168.1.100 仅允许指定的单个 IP 连接
    192.168.1.% 允许 192.168.1 网段的所有 IP 连接
    %.example.com 允许指定域名后缀的主机连接
    % 允许任意 IP 连接(最宽松)
    关于内网/公网登录的正确理解

    原文关于内网 IP 的解释有错误,这里修正:

    • 如果客户端和 MySQL 服务器在同一个内网,客户端连接时 MySQL 看到的来源 IP 就是客户端的内网 IP 本身(不经过公网和 NAT)。此时可以把 host 精确设为内网 IP 或网段(如 '192.168.1.%'),不需要设为 %。
    • 如果客户端跨公网连接 MySQL 服务器,请求经过路由器 NAT 后,MySQL 看到的来源 IP 是公网 IP。此时需要把 host 设为对应的公网 IP,或者设为 %(任意 IP)。
    • % 的含义是"任意 IP 都能连接",和内网/公网无关。设为 % 意味着全网可达,生产环境慎用,应尽量精确限制来源 IP。

    2.3 user 表核心字段解读

    user 表有几十个字段,重点关注以下几类:

    字段含义
    Host 允许登录的主机/IP(见 2.2)
    User 账号名
    authentication_string 密码的哈希摘要(不是明文密码)
    plugin 认证插件。MySQL 8.0 默认 caching_sha2_password,5.7 默认 mysql_native_password
    Select_priv、Insert_priv、Update_priv、Delete_priv 全局级别的增删改查权限,Y 表示拥有
    Create_priv、Drop_priv、Alter_priv、Grant_priv 全局级别的 DDL 和授权权限
    Super_priv 超级权限(kill 线程、修改全局变量等)
    password_expired 密码是否已过期(Y/N)
    password_last_changed 密码最后修改时间
    password_lifetime 密码有效期(天)
    account_locked 账户是否被锁定(Y 表示锁定,无法登录)

    其余字段大多是各类全局权限位(Y/N)、SSL 连接配置、资源限制(每小时最大查询数/连接数等)。

    2.4 创建用户

    语法

    CREATE USER '用户名'@'主机' IDENTIFIED BY '密码';

    示例

    — 创建一个只能本地登录的用户
    CREATE USER 'zhangsan'@'localhost' IDENTIFIED BY '123456';

    — 创建一个允许任意 IP 登录的用户
    CREATE USER 'lisi'@'%' IDENTIFIED BY '123456';

    — 创建一个允许指定网段登录的用户
    CREATE USER 'wangwu'@'192.168.1.%' IDENTIFIED BY '123456';

    注意:MySQL 8.0 中,CREATE USER 创建的用户默认没有任何权限,只能登录,连库都看不到。需要额外用 GRANT 授权。

    2.5 删除用户

    语法

    DROP USER '用户名'@'主机';

    示例

    DROP USER 'zhangsan'@'localhost';

    注意:必须写完整的 '用户名'@'主机',因为用户是由两者共同标识的。

    2.6 修改密码

    MySQL 8.0 推荐写法(标准)

    — 修改指定用户密码
    ALTER USER '用户名'@'主机' IDENTIFIED BY '新密码';

    — 修改当前登录用户自己的密码
    ALTER USER CURRENT_USER() IDENTIFIED BY '新密码';

    也可以用 SET PASSWORD

    SET PASSWORD FOR '用户名'@'主机' = '新密码';

    已经废弃的写法

    — ❌ MySQL 8.0 中已废弃/移除,会报错
    SET PASSWORD FOR '用户名'@'主机' = PASSWORD('新密码');

    PASSWORD() 函数在 MySQL 8.0 中已被移除,8.0 中直接写明文密码即可,MySQL 会自动用认证插件哈希后存储。

    2.7 权限管理

    2.7.1 权限的四个层级

    MySQL 权限从粗到细分为四个层级:

    层级语法范围作用范围
    全局权限 *.* 所有库的所有表
    数据库权限 库名.* 指定库的所有表
    表权限 库名.表名 指定库的指定表
    列权限 库名.表名(列1,列2) 指定表的指定列
    2.7.2 常用权限列表
    权限作用
    ALL PRIVILEGES / ALL 除 GRANT OPTION 和 PROXY 外的所有权限
    SELECT 查询数据
    INSERT 插入数据
    UPDATE 更新数据
    DELETE 删除数据
    CREATE 创建数据库/表
    DROP 删除数据库/表
    ALTER 修改表结构
    INDEX 创建/删除索引
    CREATE VIEW 创建视图
    SHOW VIEW 查看视图定义
    CREATE ROUTINE 创建存储过程/函数
    ALTER ROUTINE 修改/删除存储过程/函数
    EXECUTE 执行存储过程/函数
    CREATE USER 创建/删除/重命名用户
    CREATE TABLESPACE 创建/删除/修改表空间
    SHOW DATABASES 查看所有数据库
    SUPER 超级权限(kill 线程、修改全局变量、关闭服务器等)
    GRANT OPTION 将自己拥有的权限再授予其他用户
    PROCESS 查看所有会话线程(SHOW PROCESSLIST)
    RELOAD 执行 FLUSH 操作
    SHUTDOWN 关闭 MySQL 服务器
    FILE 服务器主机文件读写(LOAD DATA INFILE 等)
    LOCK TABLES 显式锁表
    CREATE TEMPORARY TABLES 创建临时表
    REPLICATION SLAVE 从库复制权限
    REPLICATION CLIENT 查询主从状态(SHOW MASTER/SLAVE STATUS)
    EVENT 创建/删除/修改事件调度器
    TRIGGER 创建/删除触发器
    REFERENCES 创建外键约束
    2.7.3 授权语法(GRANT)

    GRANT 权限列表 ON 库.对象 TO '用户名'@'主机';

    示例
    2.7.4 回收权限(REVOKE)

    REVOKE 权限列表 ON 库.对象 FROM '用户名'@'主机';

    示例

    — 回收指定库的删除权限
    REVOKE DELETE ON company.* FROM 'zhangsan'@'localhost';

    — 回收所有权限(不含 GRANT OPTION)
    REVOKE ALL PRIVILEGES ON *.* FROM 'lisi'@'%';

    — 回收 GRANT OPTION 权限
    REVOKE GRANT OPTION ON *.* FROM 'wangwu'@'%';

    2.7.5 查看用户权限

    — 查看指定用户的权限
    SHOW GRANTS FOR '用户名'@'主机';

    — 查看当前登录用户自己的权限
    SHOW GRANTS FOR CURRENT_USER();

    2.8 FLUSH PRIVILEGES 什么时候用

    FLUSH PRIVILEGES 的作用是重新加载 mysql 库中的权限表到内存。

    操作方式是否需要 FLUSH PRIVILEGES
    用 CREATE USER / DROP USER / GRANT / REVOKE / ALTER USER 等标准语句管理用户 ❌ 不需要,MySQL 自动刷新权限缓存
    直接用 INSERT / UPDATE / DELETE 手动修改 mysql.user 等权限表 ✅ 必须执行 FLUSH PRIVILEGES,否则修改不生效

    生产环境推荐始终使用标准的用户管理语句(CREATE USER / GRANT 等),不要直接修改 mysql.user 表,避免权限不一致。

    2.9 扩展:角色(Role)—— MySQL 8.0+

    MySQL 8.0 引入了角色(Role)机制,可以把一组权限打包成一个角色,再把角色授予用户,简化权限管理。

    — 创建角色
    CREATE ROLE 'app_developer', 'app_reader';

    — 给角色授权
    GRANT ALL PRIVILEGES ON app_db.* TO 'app_developer';
    GRANT SELECT ON app_db.* TO 'app_reader';

    — 把角色授予用户
    GRANT 'app_developer' TO 'zhangsan'@'localhost';

    — 用户启用角色(会话级)
    SET ROLE 'app_developer';

    — 查看当前启用的角色
    SELECT CURRENT_ROLE();

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » MySQL基础篇之视图与用户管理
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!