调用数据迁移的存储过程huike_transfer_hour完成小时表的分库
存储过程完成小时表分库: 主要逻辑是 拿到库里的所有年份 2016 2017 2018 遍历游标
DECLARE date_year VARCHAR(20);
DECLARE rs CURSOR FOR SELECT YEAR(datatime) date_year FROM report_site_hour GROUP BY YEAR(datatime);
遍历游标 动态拼接sql 更新插入到指定库
SET @table_replace = CONCAT('REPLACE INTO ipvacloud_ramus_',date_year,'.report_site_hour
select * from ipvacloud_20170424.report_site_hour a WHERE YEAR(datatime)=',date_year,'
AND a.modifytime between "',minModifytime,'" AND "',maxModifytime,'"');
PREPARE sql_oper_replace FROM @table_replace;
EXECUTE sql_oper_replace;
ipvacloud_ramus_2017
//这里查询的是分库后的小时表 如果是2个时间可以用工具类DatabaseTools获取[2016,2017]
List<Integer> list = DatabaseTools.getFromToYears("2016", "2017");
paraMap.put("year", year);
不跨库 只查询单年的小时表 SQL里直接写:
select inum from ipvacloud_ramus_${year}.report_site_hour rshpackage com.winner.common;
import java.util.ArrayList;
import java.util.List;
//获取数据库分区,即获取年份list的工具类
public class DatabaseTools {
//获取两个时间中的年份返回list,在数据库遍历[2016,2017]
public static List<Integer> getFromToYears(String from, String to){
Integer start = Integer.valueOf(from);
Integer end = Integer.valueOf(to);
List<Integer> years = new ArrayList<>();
if (start.equals(end)) {
years.add(start);
}else{
do {
years.add(start);
start++;
} while (!start.equals(end));
years.add(end);
}
return years;
}
}
这个子查询里有beginDate,endDate,siteKey,years遍历的item, 跨库查询 ipvacloud_ramus_${year}.report_site_hour
因为跨年了,所以foreach遍历,相当于关联了2个年份的小时表 小时表跨年查询的应用场景 foreach带()带别名rsh
left join (
<foreach collection="years" item="item" index="index" separator="union">select innum from ipvacloud_ramus_${item}.report_site_hour where datatime <![CDATA[>]]> #{startDate}
and datatime <![CDATA[<]]> #{endDate}
</foreach>) rsh
如下是foreach部分作为子查询生成的sql,如果不跨年,则不出现union(即子查询是本年的)
(
SELECT
innum
FROM
ipvacloud_ramus_2016.report_site_hour
WHERE
datatime > ?
AND datatime < ?
UNION
SELECT
innum
FROM
ipvacloud_ramus_2017.report_site_hour
WHERE
datatime > ?
AND datatime < ?
) rsh