创建视图与函数,你注意过 Definer是啥意思吗

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

[[415822]]

本文转载自微信公众号「MySQL技术」,作者MySQL技术。转载本文请联系MySQL技术公众号。

 前言:

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

1.DEFINER简单介绍

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

  1. CREATE 
  2.     [OR REPLACE
  3.     [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] 
  4.     [DEFINER = user
  5.     [SQL SECURITY { DEFINER | INVOKER }] 
  6.     VIEW view_name [(column_list)] 
  7.     AS select_statement 
  8.     [WITH [CASCADED | LOCALCHECK 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 三张表的查询权限。下面通过示例来具体演示下:

  1. # 创建两个视图 定义者都是testuser 查询的是test_tb表 
  2. mysql>  show grants for 'testuser'@'%'
  3. +------------------------------------------------------------------------------------------------------+ 
  4. | Grants for testuser@%                                                                                | 
  5. +------------------------------------------------------------------------------------------------------+ 
  6. GRANT USAGE ON *.* TO 'testuser'@'%'                                                                 | 
  7. GRANT SELECTINSERTUPDATEDELETECREATECREATE VIEW, SHOW VIEW ON `testdb`.* TO 'testuser'@'%' | 
  8. +------------------------------------------------------------------------------------------------------+ 
  9. rows in set (0.00 sec) 
  10.  
  11. mysql>  show create view view_definer\G 
  12. *************************** 1. row *************************** 
  13.                 View: view_definer 
  14.          Create ViewCREATE 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` 
  15. character_set_client: utf8mb4 
  16. collation_connection: utf8mb4_general_ci 
  17. 1 row in set (0.00 sec) 
  18.  
  19. mysql>  show create view view_invoker\G 
  20. *************************** 1. row *************************** 
  21.                 View: view_invoker 
  22.          Create ViewCREATE 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` 
  23. character_set_client: utf8mb4 
  24. collation_connection: utf8mb4_general_ci 
  25. 1 row in set (0.00 sec) 
  26.  
  27. # 只给uview用户查询这两个视图的权限 来进行查询测试 
  28. mysql> select user(); 
  29. +-----------------+ 
  30. user()          | 
  31. +-----------------+ 
  32. | uview@localhost | 
  33. +-----------------+ 
  34. 1 row in set (0.00 sec) 
  35.  
  36. mysql> show grants; 
  37. +--------------------------------------------------------+ 
  38. | Grants for uview@%                                     | 
  39. +--------------------------------------------------------+ 
  40. GRANT USAGE ON *.* TO 'uview'@'%'                      | 
  41. GRANT SELECT ON `testdb`.`view_definer` TO 'uview'@'%' | 
  42. GRANT SELECT ON `testdb`.`view_invoker` TO 'uview'@'%' | 
  43. +--------------------------------------------------------+ 
  44. rows in set (0.00 sec) 
  45.  
  46. mysql> select * from view_definer; 
  47. +--------+----------+ 
  48. | stu_id | stu_name | 
  49. +--------+----------+ 
  50. |   1001 | from1    | 
  51. |   1002 | dfsfd    | 
  52. |   1003 | fdgfg    | 
  53. +--------+----------+ 
  54. rows in set (0.00 sec) 
  55.  
  56. mysql> select * from view_invoker; 
  57. 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 
  58.  
  59. # 结果是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技术
相关推荐

2020-06-20 14:09:01

信息安全数据技术

2023-10-04 17:25:01

面向接口编程

2023-12-04 07:09:53

函数递归python

2012-10-08 09:19:49

2012-11-05 09:31:29

新闻回顾

2019-10-17 14:36:05

网络安全信息安全Google

2020-03-11 20:42:34

浏览器缓存机制

2021-07-12 07:59:05

对象接口编程

2021-09-25 13:12:47

数据开发架构

2021-01-22 07:48:07

JavaScript 高阶函数闭包

2018-07-24 11:52:20

2021-09-28 20:17:30

5G公网专用

2015-10-23 09:34:16

2023-10-30 00:08:43

ERPPLM网络

2023-03-13 13:36:00

Go扩容切片

2020-07-14 07:48:19

Java对象JVM

2022-01-05 12:03:48

MySQL索引数据

2022-04-28 08:12:29

函数调用进程切换代码

2023-05-29 08:11:42

@Value注解Bean

2022-04-26 21:49:55

Spring事务数据库
点赞
收藏

51CTO技术栈公众号