MySQL DEFINER详解

在 MySQL 数据库中,在创建视图及函数的时候,通常会用到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]

在上述SQL中,definer出现了两次。一次是 DEFINER = user,该语句表明该视图的定义者是user用户,若不显式指定,则创建此对象的用户就是定义者;另一次是SQL SECURITY 选项,该选项可以设置为 DEFINER 或 INVOKER。其中,当SQL SECURITY为DEFINER时,表示

执行该视图(函数/存储过程),需要使用DEFINER的权限来执行,如果DEFINER没有权限,则执行不成功。当 SQL SECURITY 属性为 INVOKER 时,则需要执行者有调用权限并且有引用的相关对象的权限(即表的增删改查等权限),才能成功执行。

2. 实验验证

以SQL SECURITY为DEFINER为例

#使用root账号操作
#1.本地可用账号test
create user `test`@`localhost` identified by123456#2.创建存储过程
CREATE DEFINER=`test`@`localhost` PROCEDURE mytest() SQL SECURITY DEFINER
BEGIN
SELECT * FROM test.`user`;
END #

#3.执行存储过程
CALL mytest();

显示:execute command denied to user 'test'@localhost' for routine 'test.mytest;

#4.赋予test用户mytest存储过程的执行权限
GRANT EXECUTE on PROCEDURE test.mytest to `test`@`localhost`;

#5.执行存储过程
CALL mytest();

显示:SELECT command denied to user 'test'@'localhost' for table 'user

#6.赋予test账号test数据库所有表的select权限
GRANT SELECT ON test.* TO `test`@`localhost`;

显示:正常

以SQL SECURITY为INVOKER为例

#使用root账号操作
#1.本地可用账号test
create user `test`@`localhost` identified by123456#2.创建存储过程
CREATE DEFINER=`test`@`localhost` PROCEDURE mytest() SQL SECURITY INVOKER
BEGIN
SELECT * FROM test.`user`;
END #

#3.执行存储过程
CALL mytest();

显示:execute command denied to user 'test'@localhost' for routine 'test.mytest;

#4.赋予test用户mytest存储过程的执行权限
GRANT EXECUTE on PROCEDURE test.mytest to `test`@`localhost`;

#5.执行存储过程
CALL mytest();

显示:正常

3. 一些注意事项

额外补充点知识,只有拥有创建权限且有 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 属性,请做好测试,清楚修改前后的区别。
  • 数据库迁移时,要注意新环境存在相关对象的定义者用户。
  • 做数据库迁移时,建议首先在新环境创建相关用户及赋予权限。

4. 参考链接

  1. MySQL DEFINER详解 - MySQL技术 - 博客园 (cnblogs.com)
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值