MySQL DEFINER具体使用详解

 更新时间:2021年08月11日 09:37:10   作者:MySQL技术  
在 MySQL 数据库中,在创建视图及函数的时候,你有注意过 definer 选项吗?本篇文章主要介绍下 MySQL 中 definer 的含义及作用,感兴趣的可以了解一下

前言:

在 MySQL 数据库中,在创建视图及函数的时候,你有注意过 definer 选项吗?在迁移视图或函数后是否有过报错情况,这些其实都可能和 definer 有关系。本篇文章主要介绍下 MySQL 中 definer 的含义及作用。

1.DEFINER简单介绍

以视图为例,我们来看下官方给出的视图创建基础语法:

CREATE
    [OR REPLACE]
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = user]
    [SQL SECURITY { DEFINER | INVOKER }]
    VIEW view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

仔细看上面语法,发现 definer 出现了两次,一次是 DEFINER = user 一次是 SQL SECURITY 选项可以设置为 DEFINER 或 INVOKER ,看到这里,你有猜到 definer 的作用了吗?

definer 翻译成中文是“定义者”的意思。MySQL中,创建视图(view)、函数(function)、存储过程(procedure)、触发器(trigger)、事件(event)时,都可以指定 DEFINER = user 选项,即指定此对象的定义者是谁,若不显式指定,则创建此对象的用户就是定义者。

对于视图、函数及存储过程,还可以指定 SQL SECURITY 属性,其值可以为 DEFINER(定义者) 或 INVOKER(调用者),表示在执行过程中,使用谁的权限来执行。DEFINER 表示按定义者拥有的权限来执行,INVOKER 表示用调用者的权限来执行。

默认情况下,SQL SECURITY 属性为 DEFINER 。其值为 DEFINER 时,数据库中必须存在 DEFINER 指定的定义者用户,并且该定义者用户拥有对应的操作权限及引用的相关对象的权限,执行者只需拥有调用权限就能成功执行。当 SQL SECURITY 属性为 INVOKER 时,则需要执行者有调用权限并且有引用的相关对象的权限,才能成功执行。

简单来说,假设一个视图查询了 a b c 三张表,若此视图的 SQL SECURITY 属性为 DEFINER ,当使用用户 u 查询此视图时,用户 u 只需此视图的查询权限即可;若此视图的 SQL SECURITY 属性为 INVOKER ,则用户 u 需要有此视图的查询权限且有 a b c 三张表的查询权限。下面通过示例来具体演示下:

# 创建两个视图 定义者都是testuser 查询的是test_tb表
mysql>  show grants for 'testuser'@'%';
+------------------------------------------------------------------------------------------------------+
| Grants for testuser@%                                                                                |
+------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'testuser'@'%'                                                                 |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE VIEW, SHOW VIEW ON `testdb`.* TO 'testuser'@'%' |
+------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql>  show create view view_definer\G
*************************** 1. row ***************************
                View: view_definer
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`testuser`@`%` SQL SECURITY DEFINER VIEW `view_definer` AS select `test_tb`.`stu_id` AS `stu_id`,`test_tb`.`stu_name` AS `stu_name` from `test_tb`
character_set_client: utf8mb4
collation_connection: utf8mb4_general_ci
1 row in set (0.00 sec)

mysql>  show create view view_invoker\G
*************************** 1. row ***************************
                View: view_invoker
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`testuser`@`%` SQL SECURITY INVOKER VIEW `view_invoker` AS select `test_tb`.`stu_id` AS `stu_id`,`test_tb`.`stu_name` AS `stu_name` from `test_tb`
character_set_client: utf8mb4
collation_connection: utf8mb4_general_ci
1 row in set (0.00 sec)

# 只给uview用户查询这两个视图的权限 来进行查询测试
mysql> select user();
+-----------------+
| user()          |
+-----------------+
| uview@localhost |
+-----------------+
1 row in set (0.00 sec)

mysql> show grants;
+--------------------------------------------------------+
| Grants for uview@%                                     |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO 'uview'@'%'                      |
| GRANT SELECT ON `testdb`.`view_definer` TO 'uview'@'%' |
| GRANT SELECT ON `testdb`.`view_invoker` TO 'uview'@'%' |
+--------------------------------------------------------+
3 rows in set (0.00 sec)

mysql> select * from view_definer;
+--------+----------+
| stu_id | stu_name |
+--------+----------+
|   1001 | from1    |
|   1002 | dfsfd    |
|   1003 | fdgfg    |
+--------+----------+
9 rows in set (0.00 sec)

mysql> select * from view_invoker;
ERROR 1356 (HY000): View 'testdb.view_invoker' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them

# 结果是view_definer查询正常,而view_invoker无法查询 因为uview用户不具有test_tb表的查询权限

自定义函数及存储过程也是类似,若 SQL SECURITY 属性为 INVOKER ,同样需要调用者有执行权限并且有引用的相关对象的权限,才能成功执行。

2.一些注意事项

额外补充点知识,只有拥有创建权限且有 SUPER 权限的用户才可以建 DEFINER = 其他用户的对象。例如:root 账号可以创建 DEFINER = testuser 的视图,而 testuser 在有创建视图的前提下只能创建 DEFINER 为自己的视图。

为了更细致的了解 DEFINER 相关作用,以视图为例再来说几个特殊情况下的示例:

假设用户 u1 不存在,使用 root 账号可以创建 DEFINER = u1 的视图,若该视图的 SQL SECURITY 属性为 DEFINER ,则查询时会报用户不存在的错误,若该视图的 SQL SECURITY 属性为 INVOKER ,则使用 root 账号可正常查询该视图。

假设用户 u2 存在但不具有查询表 a 的权限,使用 root 账号可以创建 DEFINER = u2 的视图来查询表 a ,若该视图的 SQL SECURITY 属性为 DEFINER ,则查询时报缺少权限的错误,若该视图的 SQL SECURITY 属性为 INVOKER ,则使用 root 账号可正常查询该视图。当使用用户 u2 登录时,则创建视图来查询表 a 会直接报错缺少权限,即创建不了查询表 a 的视图,无论此视图的 SQL SECURITY 属性是什么。

看完上述示例后,不清楚你对 DEFINER 是否有了更清晰的认识,有兴趣的同学可以自己测试看一看。结合笔者日常经验,说下 DEFINER 相关注意事项吧:

  • SQL SECURITY 属性建议使用默认的 DEFINER 。
  • 某个库内的视图、函数、存储过程建议使用统一的 DEFINER 用户。
  • 不要轻易修改及删除数据库用户,因为此用户可能是相关对象的定义者。
  • 若要修改 SQL SECURITY 属性,请做好测试,清楚修改前后的区别。
  • 数据库迁移时,要注意新环境存在相关对象的定义者用户。
  • 做数据库迁移时,建议首先在新环境创建相关用户及赋予权限。

总结:

本篇文章主要介绍了 DEFINER 相关知识,这些主要在创建视图、函数、存储过程等对象时会遇到,平时比较容易被忽略。但这些细节还是应该注意的,多了解多学习下,这样到真正用到的时候可以避免很多错误。

到此这篇关于MySQL DEFINER具体使用详解的文章就介绍到这了,更多相关MySQL DEFINER内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Linux系统下自行编译安装MySQL及基础配置全过程解析

    Linux系统下自行编译安装MySQL及基础配置全过程解析

    这篇文章主要介绍了Linux系统下自行编译安装MySQL及基础配置全过程解析,配置方面主要针对InnoDB引擎来讲,需要的朋友可以参考下
    2016-02-02
  • 一文带你了解MySQL中的事务

    一文带你了解MySQL中的事务

    事务处理可以用来维护数据库的完整性,保证成批的sQL语句要么全部执行,要么全部不执行。本文将通过一些简单的示例带大家了解一下MySQL中的事务,希望对大家有所帮助
    2023-02-02
  • Mysql 相邻两行记录某列的差值方法

    Mysql 相邻两行记录某列的差值方法

    今天小编就为大家分享一篇Mysql 相邻两行记录某列的差值方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • mysql 数据插入和更新及删除详情

    mysql 数据插入和更新及删除详情

    这篇文章主要介绍了mysql 数据插入和更新及删除,文章围绕mysql 数据插入和更新及删除的相关资料展开内容,需要的朋友可以参考以下文章的具体内容
    2021-10-10
  • mysql千万级数据分页查询性能优化

    mysql千万级数据分页查询性能优化

    本文给大家分享的是作者在使用mysql进行千万级数据量分页查询的时候进行性能优化的方法,非常不错的一篇文章,对我们学习mysql性能优化非常有帮助
    2017-11-11
  • Mysql误删数据解决方案及kill语句原理

    Mysql误删数据解决方案及kill语句原理

    这篇文章主要介绍了Mysql误删数据解决方案及kill语句原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • MySQL中组合字段之concat()

    MySQL中组合字段之concat()

    这篇文章主要介绍了MySQL中组合字段之concat(),MySQL是关系型数据库,我们在使用的时候往往会将对象的属性映射成列存储在表中,因此查询的到的结果在不做任何处理的情况下,也是一个个单独的属性,需要的朋友可以参考一下
    2021-11-11
  • mysql8.0.20配合binlog2sql的配置和简单备份恢复的步骤详解

    mysql8.0.20配合binlog2sql的配置和简单备份恢复的步骤详解

    这篇文章主要介绍了mysql8.0.20配合binlog2sql的配置和简单备份恢复的步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Navicat远程连接SQL Server并转换成MySQL步骤详解

    Navicat远程连接SQL Server并转换成MySQL步骤详解

    最近遇到一个需求是将SQL Server转换为 MySQL的格式,由于不想在本地安装 SQL Server,所以决定在远程的 Windows 服务器上安装,并在本地使用Navicat远程连接它,然而在实现过程中遇到了诸多问题,记录于此。感兴趣的朋友们下面来一起学习学习吧。
    2017-01-01
  • mysql性能监控工具Innotop简介及配置

    mysql性能监控工具Innotop简介及配置

    INNOTOP是一个通过文本模式显示MySQL和InnoDB的监测工具。INNOTOP是用PERL语言写成的,这使它能更加灵活的使用在各种操作平台之上,它能详细的的监控出当前MYSQL和INNODB运行的状态,以DBA根据结果,可以合理的优化MYSQL,让MYSQL更稳定更高效的运行。
    2014-08-08

最新评论