之前开发的一个监控系统,数据库的日志表是单表,虽然现在数据还不大并且做了查询sql优化,不过以后数据库的日志表数据肯定会越来越庞大,将会导致查询缓慢,所以把日志表改成分表,日志表可以按时间做水平分表,我是按月分的,每个月一张表,这时候的问题是

  1. 数据库有多张同样的分表如何根据条件查询?
  2. 在进行分页的时候如何计算总记录数?如何查询出所有分表?
  3. 每个月的新表是如何创建?系统如何自动创建?
  4. 不确定哪个分表的情况如何查询某一条详细记录?

分表查询
分表查询可以用union或者union all进行查询
union和union all都是将两个结果集合 合并在一起

select * from log_2019_05  where createTime > '2019-05-01 10:00:00'
union all
select * from log_2019_06 where createTime < '2019-06-01 10:00:00'

在我们的java程序里面,根据用户的传的查询开始时间和结束时间,就可以解析出要查询那些表,然后拼接成我们要查的sql就可以了,举例:可以把要查的表放进数组里面,然后在mybatis的查询方法的xml里面循环遍历拼接出sql

注:
union去重且排序
union all不去重不排序
性能上union all较快,比union少了排序,union是把数据合并之后还会进行排序,在排序中去掉重复的
这里的日志表没有重复的,本身就是有时间顺序,所以用union all

计算分表的总记录数
如果想要一进列表页面的分页地方要显示出总记录数,可以查询出所有的分表,然后union all拼接后用count(*),那问题又来了,如何查询出所有同样结构的分表

  1. 想法一:我们这个分表是按月分,只要在程序获取当前年月份,以及我们最早创建的表年月份,就可以计算出所有的分表(最下面有计算两个日期之间的所有月份java代码)
  2. 想法二:按月分表,我们不一定要获取数据库所有分表的总记录数,可以在查询页面给一个开始时间默认值(可以默认当月1号也可以默认三个月前等),就统计这段时间的分表
  3. 想法三:如果我们的分表不是按月分的,那么又怎么知道所有的分表呢?这时候可以在mysql中可以用information_schema数据库的tables表查询出所有的分表记录
select table_name from INFORMATION_SCHEMA.TABLES where table_name like 'log_%'


最后我采用的方案是查询页面的查询条件默认查询当前月,第一次进来日志列表页就显示当前月的分页数据,所以就不需要查询所有的分表(如果查询的时候选了开始结束时间,则计算出开始结束时间之间的所有月份,union all连接相应的月份表查询)


information_schema.tables存储了数据表的元数据信息
information_schema数据库中的表都是只读的,不能进行更新、删除和插入等操作

按月的分表,每次要怎么创建

  1. 想法一:最简单的就是手动创建,自己手工创建接下来两年的
  2. 想法二:手动创建新表不能一劳永逸,肯定得程序自动创建才行,可以用定时任务,每个月1号执行一次,创建下个月的分表,或者每一段时间执行一次,创建接下来半年或者一两年的表(如果存在则不创建)
  3. 想法三:可以在程序的新增插入日志的时候判断一次当前月的表是否存在,不存在则创建后再插入数据
  4. 想法四:想法三可以但是表每个月只需创建一次,大多数都不需要判断,每次都判断是否存在有点多余且损耗性能,在这个基础上优化,用类似乐观锁的原理,每次插入数据的时候都认为已存在该表,直接插入,当抛出表不存在的异常时,捕获这个异常时新建表,然后再插入数据

如何查询分表的某一条详细记录
在列表页面看到只是日志的概略,还有详细的日志需要点击进去详细页面查看,问题来了,以前只需要传id参数就可以了,现在在分表中,每个表都有可能有相同的id,所以只穿一个id肯定不行的,这个时候需要再多穿一个创建时间参数,在程序里面根据这个创建时间就知道是那张分表了,然后再根据id查询即可。

注:
如果分表的id采用的是全局唯一ID的方案,所有的分表id都是不一样的,也是可以直接用ID查询出来的

计算两个日期之间的所有月份

    /**
*
* @param minDate 最小时间
* @param maxDate 最大时间
* @return 日期集合 格式为 年-月
* @throws Exception
*/
public static List<String> getMonthBetween(String minDate, String maxDate) throws Exception {
ArrayList<String> result = new ArrayList<String>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMM");//格式化为年月 Calendar min = Calendar.getInstance();
Calendar max = Calendar.getInstance(); min.setTime(sdf.parse(minDate));
min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1); max.setTime(sdf.parse(maxDate));
max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2); Calendar curr = min;
while (curr.before(max)) {
result.add(sdf2.format(curr.getTime()));
curr.add(Calendar.MONTH, 1);
} return result;
} public static void main(String[] args) throws Exception{
String minDate = "2018-09-02 00:15:01";
String maxDate = "2019-06-02 00:15:01";
List<String> list = DateUtils.getMonthBetween(minDate,maxDate);
for(String date :list){
System.out.println("时间:"+date);
}
}

运行main方法结果

原文链接:https://www.csdn.net/gather_20/MtTaUg3sODk3OC1ibG9n.html

mysql如何查询多样同样的表/sql分表查询、java项目日志表分表的开发思路/按月分表的更多相关文章

  1. MySQL数据库学习笔记(六)----MySQL多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  2. MySQL多表查询之外键、表连接、子查询、索引

    MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...

  3. MySQL数据库学习笔记----MySQL多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  4. mysql学习笔记-- 多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  5. [.NET] SQL数据分页查询

    [.NET] SQL数据分页查询 程序下载 范例下载:点此下载 原始码下载:点此下载 NuGet封装:点此下载 数据查询 开发系统时,使用C#执行SQL查询指令,就可以从SQL数据库里查询所需数据. ...

  6. 使用jdbc拼接条件查询语句时如何防止sql注入

    本人微信公众号,欢迎扫码关注! 使用jdbc拼接条件查询语句时如何防止sql注入 最近公司的项目在上线时需要进行安全扫描,但是有几个项目中含有部分老代码,操作数据库时使用的是jdbc,并且竟然好多都是 ...

  7. java开发_mysql中获取数据库表描述_源码下载

    功能描述: 在mysql数据库中,有两张表: data_element_config , test_table 我们需要获取表:test_table表的描述信息,然后把描述信息插入到表:data_el ...

  8. {MySQL的逻辑查询语句的执行顺序}一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析

    MySQL的逻辑查询语句的执行顺序 阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SEL ...

  9. MySQL多表查询,Navicat使用,pymysql模块,sql注入问题

    一.多表查询 #建表 create table dep( id int, name varchar(20) ); create table emp( id int primary key auto_i ...

随机推荐

  1. LinuX操作系统基础------>了解文件结构和相关的文件操作

    了解LinuX文件系统 熟悉LinuX的文件结构 熟悉LinuX的基本操作指令 利用所学指令进行指令组合操作 什么是文件?什么是目录? 文件:一般是一个独立的东西,可以通过某些工具将其打开 目录:可以 ...

  2. SSH安全免密码登录:ssh key

    ssh key 使用非对称加密方式生成公钥和私钥 私钥存放在本地~/.ssh目录 公钥可以对外公开,放在服务器的~/.ssh/authorized_keys 1.linux平台生成ssh key ss ...

  3. Azure Application Gateway(一)对后端 Web App 进行负载均衡

    一,引言 今天,我们学习一个新的知识点-----Azure Application Gateway,通过Azure 应用程序网关为我么后端的服务提供负载均衡的功能.我们再文章头中大概先了解一下什么是应 ...

  4. CUDA线程、线程块、线程束、流多处理器、流处理器、网格概念的深入理解

    一.与CUDA相关的几个概念:thread,block,grid,warp,sp,sm. sp: 最基本的处理单元,streaming processor  最后具体的指令和任务都是在sp上处理的.G ...

  5. AutoUpdater迁移到Github

    一. 摘要 最近一两年在做跨平台的解决方案,使应用程序能支持Android, iOS, Windows, MacOs. Linux等操作系统,在Android, iOS上可以使用Google Play ...

  6. Nginx定时日志切割

    Nginx定时日志切割 现有的日志都会存在access.log文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维 人员查看,所以我们可以通过把这个大的日志文件切割为多份不 ...

  7. socket传输图片用shutdownoutput()之后无法继续传输数据

    socket传输图片用shutdownoutput()之后无法继续传输数据前言java的socket是一个全双工套接字,任何的输入流或输出流的close()都会造成Socket关闭.使用java服务器 ...

  8. 栈及其简单应用(python代码)

    栈属于线性结构(Linear Struncture),要搞清楚这个概念,首先要明白”栈“原来的意思,如此才能把握本质."栈“者,存储货物或供旅客住宿的地方,可引申为仓库.中转站,所以引入到计 ...

  9. NodeJs nrm 和 nvm

    nrm 和 nvm nrm (npm registry manager)是npm的镜像源管理工具 nvm (node version manager)是nodejs的版本管理工具 nrm # nrm ...

  10. Docker服务开放了这个端口,服务器分分钟变肉机

    之前有很多朋友提过,当使用docker-maven-plugin打包SpringBoot应用的Docker镜像时,服务器需要开放2375端口.由于开放了端口没有做任何安全保护,会引起安全漏洞,被人入侵 ...