关于mysql:MySQL-DEFINER详解

8次阅读

共计 4100 个字符,预计需要花费 11 分钟才能阅读完成。

前言:

在 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 相干常识,这些次要在创立视图、函数、存储过程等对象时会遇到,平时比拟容易被疏忽。但这些细节还是应该留神的,多理解多学习下,这样到真正用到的时候能够防止很多谬误。

正文完
 0