MySQLDEFINER具体使⽤详解
⽬录
前⾔:
1.DEFINER简单介绍
2.⼀些注意事项
总结:
前⾔:
在 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_na
me` 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'@'%' |
mysql视图和存储过程| 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内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论