MySql小技能:定时任务

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 利用MySql的事件机制完成定时任务: 在指定的时间调用指定的存储过程。

引言

I 预备知识

SQL 层面:SQL 的生命周期、权限管理、count(*) 的底层原理、底层的排序原理、连表原理。
存储引擎层面: InnoDB 存储引擎的底层架构、索引的算法、事务的原理、锁机制、隔离机制、幻读

1.1 mysql 各字段类型存储文本信息的最大值

  • text,最大65535字节
  • mediumtext,最大16777215字节
  • longtext,2的32次方减1个,即4294967295个字节

1.2 date_sub的用法

语法:date_sub(date,interval expr type),函数从日期减去指定的时间间隔,

例子:删除时间小于昨天的数据

    delete from car_viol where `create` < date_sub(curdate(), interval 1 day);

1.3 innodb_io_capacity 参数

MySQL 数据库并不是直接根据硬盘的性能来调节其 write 速度,而是靠 innodb_io_capacity 参数来告诉 MySQL 数据库磁盘的性能。

1.4 过程和函数

过程(procedure)又叫存储过程(stored procedure),是一个有名称的PL/SQL程序块 。

过程相当于java中的方法, 它注重的是实现某种业务功能 。
函数(function)也相当于java中的方法,它 注重计算并且总是有返回结果 。

过程和函数都是能够永久存储在数据库中的程序代码块,应用时通过调用执行 。
https://blog.csdn.net/z929118967/article/details/128313118

1.5 查询mysql有没有开启时间功能的支持

/*查看事件功能是否开启*/
show variables like 'event_scheduler'; 

开启事件功能

set global event_scheduler = on;
# off 代表关,on 代表开

II 定时任务

利用MySql的事件机制完成定时任务: 在指定的时间调用指定的存储过程。

event机制是mysql5.1版本开始引入的,这意味着版本低于5.1的可能无法使用

2.1 实现定时操作的功能

  • 创建了一个存储过程,它可以删除时间小于昨天的数据
create procedure del_car_v()
begin
    delete from car_v where `create` < date_sub(curdate(), interval 1 day);
end
  • 创建一个事件,让事件按照某种规则去调用存储过程。事件创建好以后就会立刻执行一次,并且一般是默认开启的。
从2023年1月2日零点开始每隔一天自动调用之前写好的存储过程。
create event `e_update_user_ticket`  
on schedule every 1 day starts '2023-01-02 00:00:00'  # 1 day 代表一天一次, 2 year(2年一次)。
on completion not preserve enable do call del_car_v(); 

2.2 控制某个事件的运行状态

/*开启事件*/
alter event 事件名 on completion preserve enable; 
/*关闭事件*/
alter event 事件名 on completion preserve disable; 

III 雪花ID

3.1 自增id作为主键的优缺点

优点:查询效率更快

数据库会选择表的主键作为聚集索引(B+Tree),mysql 在底层是以数据页为单位来存储数据的。InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的,所以主键有序比无序查询效率要快。

缺点:

  • 容易导致主键重复
比如导入旧数据时,线上又有新的数据新增,这时就有可能在导入时发生主键重复的异常。为了避免导入数据时出现主键重复的情况,要选择在应用停业后导入旧数据,导入完成后再启动应用。显然这样会造成不必要的麻烦。而UUID作为主键就不用担心这种情况。
  • 不利于数据库的扩展
当采用自增id时,分库分表也会有主键重复的问题。UUID则不用担心这种问题。

3.2 雪花ID

自增id会担心主键重复,UUID不能保证有序性,而雪花ID既是有序的,又是唯一的。

snowflake是Twitter开源的分布式ID生成算法,结果是64bit的Long类型的ID,有着全局唯一和有序递增的特点。

  • 最高位是符号位:因为生成的 ID 总是正数,始终为0。
  • 41位的时间序列:精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。
  • 10位的机器标识:10位的长度最多支持部署1024个节点。

12位的计数序列号:序列号即一系列的自增ID,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。

缺点:强依赖机器时钟,如果机器上时钟回拨,有可能会导致主键重复的问题。

3.3 Java实现雪花ID

public class SnowflakeIdWorker {
    /**
     * 开始时间:2020-01-01 00:00:00
     */
    private final long beginTs = 1577808000000L;

    private final long workerIdBits = 10;

    /**
     * 2^10 - 1 = 1023
     */
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);

    private final long sequenceBits = 12;

    /**
     * 2^12 - 1 = 4095
     */
    private final long maxSequence = -1L ^ (-1L << sequenceBits);

    /**
     * 时间戳左移22位
     */
    private final long timestampLeftOffset = workerIdBits + sequenceBits;

    /**
     * 业务ID左移12位
     */
    private final long workerIdLeftOffset = sequenceBits;

    /**
     * 合并了机器ID和数据标示ID,统称业务ID,10位
     */
    private long workerId;

    /**
     * 毫秒内序列,12位,2^12 = 4096个数字
     */
    private long sequence = 0L;

    /**
     * 上一次生成的ID的时间戳,同一个worker中
     */
    private long lastTimestamp = -1L;

    public SnowflakeIdWorker(long workerId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("WorkerId必须大于或等于0且小于或等于%d", maxWorkerId));
        }

        this.workerId = workerId;
    }

    public synchronized long nextId() {
        long ts = System.currentTimeMillis();
        if (ts < lastTimestamp) {
            throw new RuntimeException(String.format("系统时钟回退了%d毫秒", (lastTimestamp - ts)));
        }

        // 同一时间内,则计算序列号
        if (ts == lastTimestamp) {
            // 序列号溢出
            if (++sequence > maxSequence) {
                ts = tilNextMillis(lastTimestamp);
                sequence = 0L;
            }
        } else {
            // 时间戳改变,重置序列号
            sequence = 0L;
        }

        lastTimestamp = ts;

        // 0 - 00000000 00000000 00000000 00000000 00000000 0 - 00000000 00 - 00000000 0000
        // 左移后,低位补0,进行按位或运算相当于二进制拼接
        // 本来高位还有个0<<63,0与任何数字按位或都是本身,所以写不写效果一样
        return (ts - beginTs) << timestampLeftOffset | workerId << workerIdLeftOffset | sequence;
    }

    /**
     * 阻塞到下一个毫秒
     *
     * @param lastTimestamp
     * @return
     */
    private long tilNextMillis(long lastTimestamp) {
        long ts = System.currentTimeMillis();
        while (ts <= lastTimestamp) {
            ts = System.currentTimeMillis();
        }

        return ts;
    }

    public static void main(String[] args) {
        SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(7);
        for (int i = 0; i < 10; i++) {
            long id = snowflakeIdWorker.nextId();
            System.out.println(id);
        }
    }
}

其他实现例子:

3.4 应用

ID生成策略、订单号生成

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
SQL 缓存 关系型数据库
MySQL技能完整学习列表6、查询优化——3、查询缓存——4、SQL优化技巧
MySQL技能完整学习列表6、查询优化——3、查询缓存——4、SQL优化技巧
117 0
|
6月前
|
存储 关系型数据库 MySQL
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
226 0
|
18天前
|
SQL 关系型数据库 MySQL
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
定时任务频繁插入数据导致锁表问题 -> 查询mysql进程
38 1
|
3月前
|
人工智能 小程序 关系型数据库
【MySQL】黑悟空都掌握的技能,数据库隔离级别全攻略
本文以热门游戏《黑神话:悟空》为契机,深入浅出地解析了数据库事务的四种隔离级别:读未提交、读已提交、可重复读和串行化。通过具体示例,展示了不同隔离级别下的事务行为差异及可能遇到的问题,如脏读、不可重复读和幻读等。此外,还介绍了在MySQL中设置隔离级别的方法,包括全局和会话级别的调整,并通过实操演示了各隔离级别下的具体效果。本文旨在帮助开发者更好地理解和运用事务隔离级别,以提升数据库应用的一致性和性能。
142 2
【MySQL】黑悟空都掌握的技能,数据库隔离级别全攻略
|
6月前
|
SQL 关系型数据库 MySQL
MySQL技能完整学习列表10、数据导入和导出——1、数据导入(LOAD DATA, mysqldump)——2、数据导出(SELECT ... INTO OUTFILE, mysqldump)
MySQL技能完整学习列表10、数据导入和导出——1、数据导入(LOAD DATA, mysqldump)——2、数据导出(SELECT ... INTO OUTFILE, mysqldump)
116 0
|
6月前
|
存储 SQL 关系型数据库
MySQL技能完整学习列表7、存储过程和函数——1、存储过程(Stored Procedures)的创建和执行——2、函数(Functions)的创建和使用
MySQL技能完整学习列表7、存储过程和函数——1、存储过程(Stored Procedures)的创建和执行——2、函数(Functions)的创建和使用
74 0
|
5月前
|
关系型数据库 MySQL 数据挖掘
MySQL 8窗口函数详解:高效数据处理的必备技能
MySQL 8窗口函数详解:高效数据处理的必备技能
228 3
|
5月前
|
存储 关系型数据库 MySQL
21. Mysql 事件或定时任务,解放双手,轻松实现自动化
21. Mysql 事件或定时任务,解放双手,轻松实现自动化
178 1
|
5月前
|
关系型数据库 MySQL 数据库
MySQL SELECT查询实战:练习题精选,提升你的数据库查询技能
MySQL SELECT查询实战:练习题精选,提升你的数据库查询技能
|
6月前
|
存储 SQL 关系型数据库
MySQL job 定时任务
MySQL job 定时任务