需求背景:最近两天新开发了一个功能由于热表中存储数据较多导致插入查询缓慢,所以要求做数据归档
需求:以年为单位进行归档,但每个归档表又存在一个阈值
方案可以使用定时调用
下图为实现思路(流程图):
1.首先判断年度归档表是否存在,不存在则创建归档表把数据进行归档
2.存在则判断表中数据是否超过阈值,没超过则直接进行归档
3.若超过阈值则需要判断是否存在归档的子表,不存在则创建子表进行归档
4.存在则重复上述操作
下面为代码演示
1.主要逻辑
@Transactional(rollbackFor = Exception.class)@Overridepublic void dataArchiving() {//首先获取当前年份String yyyy = DateUtils.formatDate(new Date(), DateUtils.yyyy);//拼接归档表名称String tableName = "urge_send_message_log_archive_"+yyyy;//判断数据库中是否存在该表logger.info("判断数据库中是否存在"+tableName+"表");int isHave = urgeSendMessageLogService.isHaveTableName(tableName);if (isHave>0){//获取归档表当前存储数据Long count = urgeSendMessageLogService.getCount(tableName);//判断数据量是否已经达到阈值(配置类参数全部提取至配置文件)if (count > threshold){//初始化子表int i = 1;while (true){//如果大于阈值判断子表是否存在tableName = tableName+"_"+i;//判断子表是否符合归档条件if (extracted(tableName)){break;}i++;}}}else {//拷贝源表结构创建新表urgeSendMessageLogService.backUpTable(tableName);logger.info("创建归档表成功!"+tableName);}//获取当前时间String endTime = DateUtils.formatDate(new Date(), DateUtils.standard);//查询符合条件的历史数据List<UrgeSendMessageLog> dataArchivings = urgeSendMessageLogService.getDataArchiving(endTime);//把查询出来的数据存入归档表urgeSendMessageLogService.setDataArchiving(dataArchivings,tableName);//批量删除已归档数据urgeSendMessageLogService.deleteDataArchiving(endTime);}
2.判断数据库中是否存在该表SQL
SELECT COUNT(table_name)from information_schema.TABLESwhere TABLE_NAME = #{表名}
3.获取表当前存储数据
select COUNT(id) from ${表名}
4.拷贝源表结构创建新表
CREATE TABLE ${新表表名}LIKE 原表表名
5.对指定表进行批量操作
insert into ${表名} (字段,字段)values<foreach collection="dataArchivings" item="entity" separator=",">(#{entity.字段},#{entity.字段})</foreach>
注意点:
注入表名时需使用 ${}
#{}对于的变量会自动加上单引号
${}对应的变量不会加上单引号
如有问题欢迎大佬指出