一、DEFINER 基础概念
在 MySQL 中创建视图、函数、存储过程等对象时,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 直译为'定义者'。若不显式指定,默认使用当前登录用户作为定义者。对于视图、函数及存储过程,SQL SECURITY 属性决定了执行权限的来源:
- DEFINER:按定义者拥有的权限执行(默认值)。数据库中必须存在该定义者用户,且拥有对应权限。执行者只需调用权限即可。
- INVOKER:按调用者的权限执行。执行者需同时具备调用权限及被引用对象的访问权限。
通俗点讲,假设一个视图查询了表 a、b、c。若 SQL SECURITY 为 DEFINER,用户 u 查询视图时,只需视图的 SELECT 权限,底层表权限由定义者承担;若为 INVOKER,用户 u 则必须同时拥有视图和表 a、b、c 的 SELECT 权限。
我们通过一个实际案例来看:
-- 1. 查看定义者 testuser 的权限
mysql> show grants for 'testuser'@'%';
+------------------------------------------------------------------------------------------------------+
| Grants for testuser@% |
+
USAGE . @
, , , , , , `testdb`. @
( sec)
mysql view_definer\G
: view_definer
: ALGORITHMUNDEFINED DEFINER`testuser`@``
SECURITY DEFINER `view_definer` `test_tb`.`stu_id` `stu_id`,... `test_tb`
mysql view_invoker\G
: view_invoker
: ALGORITHMUNDEFINED DEFINER`testuser`@``
SECURITY INVOKER `view_invoker` `test_tb`.`stu_id` `stu_id`,... `test_tb`
mysql grants;
Grants uview@
USAGE . @
`testdb`.`view_definer` @
`testdb`.`view_invoker` @
( sec)
mysql view_definer;
stu_id stu_name
from1
dfsfd
fdgfg
( sec)
mysql view_invoker;
ERROR (HY000): invalid (s) (s)...
definerinvoker lack rights use them

