数据库中单表数据存储量过大时,会造成数据库的查询统计速度变慢,因此需将单表数据拆分存储到按年月命名的多张数据表中。解决思路是获取单表中的最小时间和最大时间,然后计算两个时间中的月份数量,最后根据开始年月循环算出所有需要拆分的年月名称,生成对应的数据表名,并将对应年月的数据存储到多张数据表中。
计算两个日期之间的相关函数如下:
// 计算两个日期之间的月份数
int Tools::MonthsBetween2Date(QString date1, QString date2) //主调函数
{ //取出日期中的年月日int year1, month1, day1;int year2, month2, day2;QString datelast,datenow;datelast=date1;datenow=date2;QRegExp exp("[年月日-:-: ]");datelast =datelast.replace(exp,"");datenow =datenow.replace(exp,"");qDebug()<<datelast;qDebug()<<datenow;if(datenow<datelast){return -1;}if(!StringToDate(datelast, year1, month1, day1) || !StringToDate(datenow, year2,month2,day2)) //调用截取函数{return -1; //如果截取信息失败,那么将返回-1}if(year1 == year2) //如果年份相同,则返回月份相减数据{if(month1 == month2){return 0;}else{return month1 > month2 ? month1 - month2 : month2 - month1;}}else //如果年份不同,则重新计算{if(year1 > year2) //如果前方数据大于后方,这调换这两数据{swap(year1, year2); //按亦或算法交换两个数swap(month1, month2);swap(day1, day2);}int m1 = MonthInYear(month1);int m2 = 12 - MonthInYear(month2) + 1;int m3 = 0;for(int year = year1 + 1; year < year2; year++){for(int k = month1; k <= 12; k++){m3 += 1;}}return m1 + m2 + m3;}
}
//字符串转年月日
bool Tools::StringToDate(QString date ,int& year, int& month, int& day) //数据解析
{year = date.mid(0,4).toInt(); //数据截取month = date.mid(4,2).toInt(); //数据截取day = date.mid(6,2).toInt(); //数据截取int DAY[12]={31,28,31,30,31,30,31,31,30,31,30,31}; //初始化12个月份的数据if(IsLeap(year)) //如果是闰年,那么将2月的数据更新为29天{DAY[1] = 29;}return year >= 0 && month<=12 && month>0 && day<=DAY[month-1] && day>0; //年天算法,判断数据解析是否符合日期规格
}
//判断是否是闰年
bool Tools::IsLeap(int year)
{return (year % 4 ==0 || year % 400 ==0) && (year % 100 !=0); //判断是否是润年
}
//计算一年中的剩余月份数量
int Tools::MonthInYear(int month)
{int intMonth = 0;for(int k = month; k <= 12; k++){intMonth += 1;}return intMonth;
}
//交换两个数
void Tools::swap(int a,int b)
{a=a^b;b=a^b;a=a^b;
}
举例:开始时间为2023-01-01 00:00:00,结束时间为2024-03-04 08:30:00,调用代码
QString date1 = "2023-01-01 00:00:00";
QString date2 = "2024-03-04 08:30:00";
int TotalMonth = MonthsBetween2Date(date1, date2);
计算的出来的月份数量为15个月。