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

之前开发的一个监控系统,数据库的日志表是单表,虽然现在数据还不大并且做了查询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

原文地址:https://www.cnblogs.com/ztf20/p/12304593.html

时间: 2024-10-18 09:14:36

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

EF中自编写SQL脚本查询结果(适用于复杂SQL逻辑提高查询效率)

前不久项目开发过程中,使用的是Entity Framework做数据处理.因为本人也不是对EF太有研究,只是会用而已,但是在一次需要查询的结果需要关联3.4个表来查询出来结果,并且对查询效率也有要求.但是个人觉得遇到这样的情况还是使用原始SQL语句来查询更为可控(或许EF中有更好的方法可以解决此类问题,但恕本人愚笨只想到了这种方法).就又自己扩展出一个方法,用来专门查询自定义编写的SQL语句.代码如下: public List<T> ExecuteStoreQuery(string comma

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

一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, 外键可以有重复的, 可以是空值,用来和其他表建立联系用的.所以说,如果谈到了外键,一定是至少涉及到两张表.例如下面这两张表: 上面有两张表:部门表(dept).员工表(emp).Id=Dept_id,而Dept_id就是员工表中的外键:因为员工表中的员工需要知道自己属于哪个部门,就可以通过外键Dep

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

注:本文转自:http://www.cnblogs.com/smyhvae/p/4042303.html 本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, 外键可以有重复的, 可以是空值,用来和其他表建立联系用的.所以说,如果谈到了外键,一定是至少涉及到两张表.例如下面这两张表: 上面有两

[.NET] SQL数据分页查询

[.NET] SQL数据分页查询 程序下载 范例下载:点此下载 原始码下载:点此下载 NuGet封装:点此下载 数据查询 开发系统时,使用C#执行SQL查询指令,就可以从SQL数据库里查询所需数据. SELECT Id, Name FROM Users 数据分页查询 当数据量过多时,系统会需要采用分页的方式来分批取得数据.这时可以改写原有的SQL查询指令,在其中加入ROW_NUMBER(),来为每笔资料打上编号.后续依照系统需求,取得某个编号范围内的数据,就完成在系统中提供数据分页查询的功能.(

MySQL中如何查看“慢查询”,如何分析执行SQL的效率?

一.MySQL数据库有几个配置选项可以帮助我们及时捕获低效SQL语句 1,slow_query_log这个参数设置为ON,可以捕获执行时间超过一定数值的SQL语句. 2,long_query_time当SQL语句执行时间超过此数值时,就会被记录到日志中,建议设置为1或者更短. 3,slow_query_log_file记录日志的文件名. 4,log_queries_not_using_indexes这个参数设置为ON,可以捕获到所有未使用索引的SQL语句,尽管这个SQL语句有可能执行得挺快. 二

MySQL数据库优化技术之SQL语句慢查询定位

通过show status命令了解各种SQL的执行频率 MySQL客户端连接成功后,通过使用show [session|global] status 命令可以提供服务器状态信息: 其中的session来表示当前的连接的统计结果,global来表示自数据库启动至今的统计结果,默认是session级别的. show status 常用命令: show status like 'com_%'; 其中com_xxx表示xxx语句所执行的次数: 重点注意com_select, com_insert, co

mysql操作命令梳理(5)-执行sql语句查询即mysql状态说明

在日常mysql运维中,经常要查询当前mysql下正在执行的sql语句及其他在跑的mysql相关线程,这就用到mysql processlist这个命令了.mysql> show processlist;            //查询正在执行的sql语句mysql> show full processlist;       //查询正在执行的完整sql语句mysql> kill connection id           //停掉processlist查询出的某个线程,id是对应的

MySQL单表多字段模糊查询解决方法

在最近的一个项目需要实现在单表中对多字段进行多个关键字的模糊查询,但这数个关键字并不一定都存在于某个字段 例如现有table表,其中有title,tag,description三个字段,分别记录一条资料的标题,标签和介绍.然后根据用户输入的查询请求,将输入的字串通过空格分割为多个关键字,再在这三个字段中查询包含这些关键字的记录. 可目前遇到的问题是,这些关键字是可能存在于三个字段中的任意一个或者多个,但又要求三个字段必须包含所有的关键词.如果分别对每个字段进行模糊匹配,是没法实现所需的要求,由此

mysql执行sql及慢查询监控

[前言] mysql可以记录用户执行的sql:记录到文件.表格 mysql可以定义执行多少时间以上得sql属于慢查询,也会根据配置,记录相关信息到文件.表格 [背景说明] 公司想监控记录每天执行了哪些sql,哪些sql是慢查询,然后去优化sql [技术说明] 其实只要搞清楚了mysql怎样记录执行sql的 怎样记录慢查询的即可 接下来就是写代码去梳理成报告,我这里使用的是python [最终效果如下] [技术细节] 1.修改my.cnf #整体的效果,全局开启表和日志文件都写,但是对于gener