用存储过程、定时器、触发器来解决数据分析问题

我会带着你远行 2024-03-30 15:28 82阅读 0赞

做数据分析或者数据处理,我们也需要掌握这些技能,来解决特定的业务问题。比如:做自动化报表,如果数据需要每天实时更新(增量爬虫)、定时计算某个业务指标 、想要实时监控数据库表中的数据增、删、改情况等。

文章大纲

9a5c9531b47630cd7806280b22986237.jpeg

一、存储过程

1、啥是存储过程,有什么用?

  • 过程 :将若干条 SQL 语句封装起来,起个名字
  • 存储过程 : 我们将此过程存储在数据库中,有点类似于编程中用到的函数,区别是函数有返回值,而过程没有返回值,相同点是将代码封装可复用,可传参,调用即可执行。
  • 好处:① 代码封装可复用 ② 可以接收、返回参数 ③ 减少网络交互、提升效率

2、存储过程如何使用

创建

  1. create procedure 名称()
  2. begin
  3. sql语句;
  4. end

b4477cd01c08495237de2f78ee648d55.jpeg

查看

  1. show procedure status;

101c0a34547006aa375f33f45db1451e.jpeg

调用

  1. call 名称();

4e143aa18ebc47346fa97ac50c992f18.jpeg

删除

  1. drop procedure if exists 名称;

3、存储过程中的变量

变量的种类和定义

在 SQL 中变量分为两种:

  • ① 系统变量:@@
  • ② 自定义变量:@

fdf632d74e42ac1808a57ebdfa0dc7b4.jpeg

34e916cffa3023cda5461e6490e592b2.jpeg

存储过程是可以编程的,意味着可以使用变量、表达式、控制结构,在存储过程中,声明变量用 declare

  1. 格式:declare 变量名 变量类型 default 默认值】

ffea831e2dc5eb614527c9c25a1af46b.jpeg

变量运算与控制结构

变量的赋值,有两种方式:

  • ① set 变量名 = 值
  • ② set 变量名 := 值

5e69c17b04606891fca6b219185afdc0.jpeg

if | else 控制结构语法格式

  1. if 条件1 then
  2. sql 语句;
  3. else if 条件2 then
  4. sql 语句;
  5. else
  6. sql语句;
  7. end if

7488dd94eb57db78f28fb8be526fced4.jpeg

存储过程中的参数传递

为了让存储过程更加灵活,可以传递参数,参数分为三种:

  • ① in:参数作为输入,调用时传入
  • ② out:参数作为输出,可以作为返回值
  • ③ inout:参数即可传入又可输入

    格式: in|out|inout 参数名 参数类型

5962721549751c0d8777cbe4da2ca299.jpeg

存储过程中使用循环

while 循环格式:

  1. while 条件 do
  2. sql 语句;
  3. end while

打印 1 - 100 之和

6b789f864e99ea3d34ac3740081f9aca.jpeg

带输入参数n,求1-n之和

3bb79334d17d75693b6a092cd88083b9.jpeg

要求带输入参数 n,和输出参数 total ,求1-n 之和

ffe3331bce369f7e0a63b75561375cb3.jpeg

要求 age 既是输入又是输出变量,传入一个年龄,就增加 20

81578a117a98a3577611599dc584458e.jpeg

二、定时器

1、啥是定时器,怎么用?

所谓定时器,就是定时地去运行指定的函数和代码,MySQL 的定时器就是 MySQL 的事件。

在开发过程中经常会遇到这样一个问题:每天或每月需定时去执行一条 SQL 语句或更新或删除数据。在我不了解 MySQL 定时器时,是用 Python 程序代码去操作数据表,再将 Python 程序,放到服务器跑定时任务。现在用定时器,完全可以在数据层面操作了,非常方便。

语法结构

  1. create event [if not exists] 事件名
  2. [definer = user] 可选参数。执⾏事件的⽤⼾,不指定默认就是当前⽤⼾
  3. on schedule 定时时间设置。定义事件执⾏的频率,可以指定具体时间也可以周期性执行
  4. [on completion [not] preserve ] 可选参数。默认是not,表⽰时间过期后会⽴即删除(注意不是不激活);on completion preserve 表⽰时间过期后会继续保留
  5. [enable | disable | disable on slave] 可选参数。默认enable。事件激活、不激活、从服务上不激活(事件在主服务商创建并赋值到从服务器上,仅在主服务上执行)
  6. [comment "注释"] 可选参数。
  7. do 事件内容 定义事件的sql语句,如果语句有多⾏需要⽤ begin end 括起来

指定时间定时执行

at子句:这里要求是timestamp时间格式,⼀般格式是“时间点 + interval 时间单位”。表示在什么时间节点执行,例如:current_timestamp + interval 2 minute

要求:两分钟后往 event_test 表插⼊⼀条语句”事件启动了”

0a71a4e6335e8c47575d4f3a22085fae.jpeg

a0aabf170e79e80973d6ec6cb29d2e0d.jpeg

注意:因为参数默认是 on completion not preserve,事件运行完成后会自动删除

周期时间定时执行:

  • every子句:格式是“数字+时间单位”,表示时间周期,例如:1 hour / 2 minute / 3 second
  • starts子句:可选,跟上 timestamp 值,表示事件开始的时间点,如果没有指定就是当前时间
  • ends子句:可选,跟上 timesatamp 值,表示停止执行的时间,如果没有ends表示无限执行

要求:新建数据表 event_test,每分钟往里面插⼊⼀条数据,到 5 分钟结束

f109c13d50eba131ebfe3b871db3c83b.jpeg

a1835f1b1257dd206187d80a6bed73e3.jpeg

注意事项

1、需要激活事件,事件才会被执行,show events才可以查看。⼀个是全局参数开启,⼀个是事件的开启

  1. SET GLOBAL event_scheduler = 1;
  2. 设置事件的状态为 enable
  3. ALTER EVENT event_name ON COMPLETION PRESERVE ENABLE; 开启
  4. ALTER EVENT event_name ON COMPLETION PRESERVE DISABLE; 关闭

2、关掉了 navicat,事件不会关闭,关闭了 MySQL 服务器才会被关闭
3、多语句执行的时候,可能需要修改结束分隔符,比如:delimiter $
4、如果事件的开始时间已经过去了,虽然创建语句不会报错,但是事件不会被创建以及执行
5、事件⾥⾯不能嵌套事件,但是存储过程里面可以使用事件
6、在事件中使用 select、show 等返回结果语句没有意义,但是可以用 select into、insert into 等存储结果的语句
7、注意不要短周期内重复事件调度,不然数据会有问题。例如每分钟执行 100w 行数据,那这个会有问题,如果实在是需要那这个时候可以使用行锁、表锁来进行
8、事件⽆法传递参数,但是可以用事件里面的参数使用存储过程

定时器可以结合存储过程

现在用定时器,就可以在数据层面操作,定时去执行sql 语句或一组 sql 语句(存储过程),设置好定时任务,可通过 navicat —— 其它——事件,查看到当前事件的定义,计划,当然也可以手动完成上述操作。

5d6747b50425aa57ac1e3be60b29c4a0.jpeg

2a783af5e42d84498c7c28bdc0f2ed41.jpeg

三、触发器

1、啥是触发器,应用场景是?

触发器是一类特殊的事务,可以监视数据操作(数据表的变更日志),包括 insert | update | delete,并触发相关操作 insert | update | delete,运用触发器,不仅能简化程序,又可以增加程序的灵活性。

应用场景①:当向一张表中添加或删除数据时,需要在相关表中进行同步操作,比如:当一个订单产生时,订单所购的产品的库存量相应减少。

应用场景②:当表中某列数据的值与其他表中的数据有联系时,比如:某客户进行欠款消费,可以在生成订单时,设计触发器判断该用户的累计欠款是否超过最大限度。

应用场景③:跟踪某张表时,比如当有新订单产生时,需通知相关人员进行处理,这时可以在订单表中添加触发器加以实现。

2、触发器如何使用

创建

触发器只支持行级触发(每一行受影响,触发器都执行,叫作行级触发器),不支持语句级触发。

2d1720dc1c524939d1a6370c725d6f9f.jpeg

  1. Create trigger 触发器名称
  2. before/after
  3. insert/update/delete
  4. on 表名 for each row #行级触发器
  5. Begin
  6. trigger_state;
  7. end

查看

  1. Show triggers;

删除

  1. Drop trigger 数据库.触发器名称;

要求:现有商品表 goods,订单表 orders,当下一个订单时,商品要相应减少(买几个商品,就少几个库存), 分析如下:

  • 监视谁:orders
  • 监视动作:insert
  • 触发时间:after
  • 触发事件:update

    CREATE TABLE goods(gid INT,name VARCHAR(10),num SMALLINT);
    CREATE TABLE ord(oid INT ,gid INT, buy_num SMALLINT)
    INSERT INTO goods VALUES (1,’cat’,20),(2,’dog’,90),(3,’pig’,26);

cdabaa59174c1055c1fa03818cbae72d.jpeg

查看商品表

d3b79cbdd80d7aa0ab1d2fe60b768333.jpeg

创建触发器并查看

729dad855631fff6945f3c5fdfa20d69.jpeg

发现这样写触发器并不灵活

3、触发器引用行变量

使用别名 old、new 来引用触发器中发生变化的记录内容。注意:

dc1ceb3fa4f21993377305aac2c289c5.jpeg

引用行变量

要求:删除一个订单时,商品要退回,库存量要还原(删)

a3c4b897d65767660e2a20dfeec0a93a.jpeg

要求:订单表中的数量3 要求改到2,并且让商品表的库存量也变化(改)

304b3d80d671fbfea29e4072e73b4b07.jpeg

7320718e23e5255dfb85be34a9c15424.jpeg

f4313fb0a28a3403c2a362f0ee696b11.jpeg

要求:假如现在剩余 26 只pig,但是客户下订单买27只,能否预防,能否将buy_num > num 时,将buy_num 自动改为 num(深入理解before 和after的区别)

b94bfd0e3578a0f4da0947c60b7e84e0.jpeg

46768766aecbf832e6ffdef84c7150e5.jpeg

上面跟大家介绍了,如何数据分析工作中,应用 MySQL 的存储过程、定时器、触发器来实现自动化更新数据。当然,用 Python 或其他编程语言也能实现,个人认为在数据层面操作,更加简单、高效、稳定。具体还要看你当下的业务场景。希望通过本文能为你提供一个解决问题的思路。

发表评论

表情:
评论列表 (有 0 条评论,82人围观)

还没有评论,来说两句吧...

相关阅读

    相关 存储过程触发器

    存储过程:存储过程是一组预编译的SQL语句,可以在数据库中存储并重复使用。存储过程可以提高性能、减少网络流量并提高安全性。MSSQL中的存储过程使用T-SQL编写。 触发器:

    相关 mysql触发器 存储过程

    一、触发器 MYSQL包含对触发器的支持,触发器是一种与表操作有关的数据库对象,当触发器在表上出现指定事件时,调用该对象,也就是说表的操作事件触发表上的触发器执行。 创

    相关 存储过程触发器

    存储过程与触发器 一、定义 存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。存储过程可包含程序流、逻辑及对数据库的查询。它们可以接受参数、输出参