热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql事件怎么处理,mysql删除事件

怎么样对MySQL中的事件进行调度怎么样对MySQL中的事件进行调度一、概述事件调度器是在MySQL5.1中新增的另一个特色功能,可以作为定时任务调度器,取代部分原先只能用操作系统

怎么样对MySQL中的事件进行调度

怎么样对MySQL中的事件进行调度

一、概述

事件调度器是在 MySQL 5.1 中新增的另一个特色功能,可以作为定时任务调度器,取代部分原先只能用操作系统任务调度器才能完成的定时功能。例如,Linux 中的 crontabe 只能精确到每分钟执行一次,而 MySQL 的事件调度器则可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。

事件调度器是定时触发执行的,在这个角度上也可以称作是"临时的触发器"。触发器只是针对某个表产生的事件执行一些语句,而事件调度器则是在某一个(间隔)时间执行一些语句。事件是由一个特定的线程来管理的,也就是所谓的"事件调度器"。启用事件调度器后,拥有 SUPER 权限的账户执行 SHOW PROCESSLIST 就可以看到这个线程了。通过设定全局变量event_scheduler 的值即可动态的控制事件调度器是否启用。

代码如下:

(root:localhost:)test SET GLOBAL event_scheduler = ON;

(root:localhost:)test show processlist\G

*************************** 4. row ***************************

Id: 46147

User: event_scheduler

Host: localhost

db: NULL

Command: Daemon

Time: 1

State: Waiting on empty queue

Info: NULL

如上,该线程的所有者是 event_scheduler。

二、应用案例

本案例是利用 event scheduler 的特性,每秒钟调用一次存储过程,用于判断 SLAVE 是否正常运行,如果发现 SLAVE 关闭了,忽略 0 次错误,然后重新启动 SLAVE。

首先创建存储过程

delimiter //

代码如下:

create procedure `Slave_Monitor`()

begin

SELECT VARIABLE_VALUE INTO @SLAVE_STATUS

FROM information_schema.GLOBAL_STATUS

WHERE VARIABLE_NAME='SLAVE_RUNNING';

IF ('ON' != @SLAVE_STATUS) THEN

SET GLOBAL SQL_SLAVE_SKIP_COUNTER=0;

SLAVE START;

END IF;

end; //

delimiter ;

由于存储过程中无法调用类似 SHOW SLAVE STATUS 这样的语句,因此无法得到确切的复制错误信息和错误代码,不能进一步的处理 SLAVE 停止的各种情况。

接着,创建任务

代码如下:

CREATE EVENT IF NOT EXISTS `Slave_Monitor`

ON SCHEDULE EVERY 5 SECOND

ON COMPLETION PRESERVE

DO

CALL Slave_Monitor();

创建了一个任务,每 5秒钟 执行一次,任务结束后依旧保留该任务,而不是删除。当然了,在本例中的任务不会结束,除非将它手动禁止了。

如果在运行中想要临时关闭一下某个任务,执行 ALTER EVENT 语句即可:

代码如下:

(root:localhost:)test alter event `Slave_Monitor` ON

COMPLETION PRESERVE DISABLE;

(root:localhost:)test alter event `Slave_Monitor` ON

COMPLETION PRESERVE ENABLE;

MySQL知识点总结

只要字段值还可以继续拆分,就不满足第一范式。

范式设计得越详细,对某些实际操作可能会更好,但并非都有好处,需要对项目的实际情况进行设定。

在满足第一范式的前提下,其他列都必须完全依赖于主键列。 如果出现不完全依赖,只可能发生在联合主键的情况下:

实际上,在这张订单表中,product_name 只依赖于 product_id ,customer_name 只依赖于 customer_id。也就是说,product_name 和 customer_id 是没用关系的,customer_name 和 product_id 也是没有关系的。

这就不满足第二范式:其他列都必须完全依赖于主键列!

拆分之后,myorder 表中的 product_id 和 customer_id 完全依赖于 order_id 主键,而 product 和 customer 表中的其他字段又完全依赖于主键。满足了第二范式的设计!

在满足第二范式的前提下,除了主键列之外,其他列之间不能有传递依赖关系。

表中的 customer_phone 有可能依赖于 order_id 、 customer_id 两列,也就不满足了第三范式的设计:其他列之间不能有传递依赖关系。

修改后就不存在其他列之间的传递依赖关系,其他列都只依赖于主键列,满足了第三范式的设计!

查询每门课的平均成绩。

查询 score 表中至少有 2 名学生选修,并以 3 开头的课程的平均分数。

分析表发现,至少有 2 名学生选修的课程是 3-105 、3-245 、6-166 ,以 3 开头的课程是 3-105 、3-245。也就是说,我们要查询所有 3-105 和 3-245 的 degree 平均分。

查询所有学生的 name,以及该学生在 score 表中对应的 c_no 和 degree 。

通过分析可以发现,只要把 score 表中的 s_no 字段值替换成 student 表中对应的 name 字段值就可以了,如何做呢?

查询所有学生的 no 、课程名称 ( course 表中的 name ) 和成绩 ( score 表中的 degree ) 列。

只有 score 关联学生的 no ,因此只要查询 score 表,就能找出所有和学生相关的 no 和 degree :

然后查询 course 表:

只要把 score 表中的 c_no 替换成 course 表中对应的 name 字段值就可以了。

查询所有学生的 name 、课程名 ( course 表中的 name ) 和 degree 。

只有 score 表中关联学生的学号和课堂号,我们只要围绕着 score 这张表查询就好了。

只要把 s_no 和 c_no 替换成 student 和 srouse 表中对应的 name 字段值就好了。

首先把 s_no 替换成 student 表中的 name 字段:

再把 c_no 替换成 course 表中的 name 字段:

查询 95031 班学生每门课程的平均成绩。

在 score 表中根据 student 表的学生编号筛选出学生的课堂号和成绩:

这时只要将 c_no 分组一下就能得出 95031 班学生每门课的平均成绩:

查询在 3-105 课程中,所有成绩高于 109 号同学的记录。

首先筛选出课堂号为 3-105 ,在找出所有成绩高于 109 号同学的的行。

查询所有成绩高于 109 号同学的 3-105 课程成绩记录。

查询所有和 101 、108 号学生同年出生的 no 、name 、birthday 列。

查询 '张旭' 教师任课的学生成绩表。

首先找到教师编号:

通过 sourse 表找到该教师课程号:

通过筛选出的课程号查询成绩表:

查询某选修课程多于5个同学的教师姓名。

首先在 teacher 表中,根据 no 字段来判断该教师的同一门课程是否有至少5名学员选修:

查看和教师编号有有关的表的信息:

我们已经找到和教师编号有关的字段就在 course 表中,但是还无法知道哪门课程至少有5名学生选修,所以还需要根据 score 表来查询:

根据筛选出来的课程号,找出在某课程中,拥有至少5名学员的教师编号:

在 teacher 表中,根据筛选出来的教师编号找到教师姓名:

查询 “计算机系” 课程的成绩表。

思路是,先找出 course 表中所有 计算机系 课程的编号,然后根据这个编号查询 score 表。

查询 计算机系 与 电子工程系 中的不同职称的教师。

查询课程 3-105 且成绩 至少 高于 3-245 的 score 表。

查询课程 3-105 且成绩高于 3-245 的 score 表。

查询某课程成绩比该课程平均成绩低的 score 表。

查询所有任课 ( 在 course 表里有课程 ) 教师的 name 和 department 。

查询 student 表中至少有 2 名男生的 class 。

查询 student 表中不姓 "王" 的同学记录。

查询 student 表中每个学生的姓名和年龄。

查询 student 表中最大和最小的 birthday 值。

以 class 和 birthday 从大到小的顺序查询 student 表。

查询 "男" 教师及其所上的课程。

查询最高分同学的 score 表。

查询和 "李军" 同性别的所有同学 name 。

查询和 "李军" 同性别且同班的同学 name 。

查询所有选修 "计算机导论" 课程的 "男" 同学成绩表。

需要的 "计算机导论" 和性别为 "男" 的编号可以在 course 和 student 表中找到。

建立一个 grade 表代表学生的成绩等级,并插入数据:

查询所有学生的 s_no 、c_no 和 grade 列。

思路是,使用区间 ( BETWEEN ) 查询,判断学生的成绩 ( degree ) 在 grade 表的 low 和 upp 之间。

准备用于测试连接查询的数据:

分析两张表发现,person 表并没有为 cardId 字段设置一个在 card 表中对应的 id 外键。如果设置了的话,person 中 cardId 字段值为 6 的行就插不进去,因为该 cardId 值在 card 表中并没有。

要查询这两张表中有关系的数据,可以使用 INNER JOIN ( 内连接 ) 将它们连接在一起。

完整显示左边的表 ( person ) ,右边的表如果符合条件就显示,不符合则补 NULL 。

完整显示右边的表 ( card ) ,左边的表如果符合条件就显示,不符合则补 NULL 。

完整显示两张表的全部数据。

在 MySQL 中,事务其实是一个最小的不可分割的工作单元。事务能够 保证一个业务的完整性 。

比如我们的银行转账:

在实际项目中,假设只有一条 SQL 语句执行成功,而另外一条执行失败了,就会出现数据前后不一致。

因此,在执行多条有关联 SQL 语句时, 事务 可能会要求这些 SQL 语句要么同时执行成功,要么就都执行失败。

在 MySQL 中,事务的 自动提交 状态默认是开启的。

自动提交的作用 :当我们执行一条 SQL 语句的时候,其产生的效果就会立即体现出来,且不能 回滚 。

什么是回滚?举个例子:

可以看到,在执行插入语句后数据立刻生效,原因是 MySQL 中的事务自动将它 提交 到了数据库中。那么所谓 回滚 的意思就是,撤销执行过的所有 SQL 语句,使其回滚到 最后一次提交 数据时的状态。

在 MySQL 中使用 ROLLBACK 执行回滚:

由于所有执行过的 SQL 语句都已经被提交过了,所以数据并没有发生回滚。那如何让数据可以发生回滚?

将自动提交关闭后,测试数据回滚:

那如何将虚拟的数据真正提交到数据库中?使用 COMMIT :

事务的实际应用 ,让我们再回到银行转账项目:

这时假设在转账时发生了意外,就可以使用 ROLLBACK 回滚到最后一次提交的状态:

这时我们又回到了发生意外之前的状态,也就是说,事务给我们提供了一个可以反悔的机会。假设数据没有发生意外,这时可以手动将数据真正提交到数据表中:COMMIT 。

事务的默认提交被开启 ( @@AUTOCOMMIT = 1 ) 后,此时就不能使用事务回滚了。但是我们还可以手动开启一个事务处理事件,使其可以发生回滚:

仍然使用 COMMIT 提交数据,提交后无法再发生本次事务的回滚。

事务的四大特征:

事务的隔离性可分为四种 ( 性能从低到高 ) :

查看当前数据库的默认隔离级别:

修改隔离级别:

测试 READ UNCOMMITTED ( 读取未提交 ) 的隔离性:

由于小明的转账是在新开启的事务上进行操作的,而该操作的结果是可以被其他事务(另一方的淘宝店)看见的,因此淘宝店的查询结果是正确的,淘宝店确认到账。但就在这时,如果小明在它所处的事务上又执行了 ROLLBACK 命令,会发生什么?

这就是所谓的 脏读 ,一个事务读取到另外一个事务还未提交的数据。这在实际开发中是不允许出现的。

把隔离级别设置为 READ COMMITTED :

这样,再有新的事务连接进来时,它们就只能查询到已经提交过的事务数据了。但是对于当前事务来说,它们看到的还是未提交的数据,例如:

但是这样还有问题,那就是假设一个事务在操作数据时,其他事务干扰了这个事务的数据。例如:

虽然 READ COMMITTED 让我们只能读取到其他事务已经提交的数据,但还是会出现问题,就是 在读取同一个表的数据时,可能会发生前后不一致的情况。* 这被称为* 不可重复读现象 ( READ COMMITTED ) 。

将隔离级别设置为 REPEATABLE READ ( 可被重复读取 ) :

测试 REPEATABLE READ ,假设在两个不同的连接上分别执行 START TRANSACTION :

当前事务开启后,没提交之前,查询不到,提交后可以被查询到。但是,在提交之前其他事务被开启了,那么在这条事务线上,就不会查询到当前有操作事务的连接。相当于开辟出一条单独的线程。

无论小张是否执行过 COMMIT ,在小王这边,都不会查询到小张的事务记录,而是只会查询到自己所处事务的记录:

这是 因为小王在此之前开启了一个新的事务 ( START TRANSACTION ) * ,那么* 在他的这条新事务的线上,跟其他事务是没有联系的 ,也就是说,此时如果其他事务正在操作数据,它是不知道的。

然而事实是,在真实的数据表中,小张已经插入了一条数据。但是小王此时并不知道,也插入了同一条数据,会发生什么呢?

报错了,操作被告知已存在主键为 6 的字段。这种现象也被称为 幻读,一个事务提交的数据,不能被其他事务读取到 。

顾名思义,就是所有事务的 写入操作 全都是串行化的。什么意思?把隔离级别修改成 SERIALIZABLE :

还是拿小张和小王来举例:

此时会发生什么呢?由于现在的隔离级别是 SERIALIZABLE ( 串行化 ) ,串行化的意思就是:假设把所有的事务都放在一个串行的队列中,那么所有的事务都会按照 固定顺序执行 ,执行完一个事务后再继续执行下一个事务的 写入操作 ( 这意味着队列中同时只能执行一个事务的写入操作 ) 。

根据这个解释,小王在插入数据时,会出现等待状态,直到小张执行 COMMIT 结束它所处的事务,或者出现等待超时。

转载:

怎么用mysql处理这样的问题?

通常情况下在PHP中MySQL查询是串行的,如果能实现MySQL查询的异步化,就能实现多条SQL语句同时执行,这样就能大大地缩短MySQL查询的耗时,提高数据库查询的效率。目前MySQL的异步查询只在MySQLi扩展提供,查询方法分别是:

1、使用MYSQLI_ASYNC模式执行mysqli::query

2、获取异步查询结果:mysqli::reap_async_query

使用mysql异步查询,需要使用mysqlnd作为PHP的MySQL数据库驱动。

使用MySQL异步查询,因为需要给所有查询都创建一个新的连接,而MySQL服务端会为每个连接创建一个单独的线程进行处理,如果创建的线程过多,则会造成线程切换引起系统负载过高。Swoole中的异步MySQL其原理是通过MYSQLI_ASYNC模式查询,然后获取mysql连接的socket,加入到epoll事件循环中,当数据库返回结果时会回调指定函数,这个过程是完全异步非阻塞的。


推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
author-avatar
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有