MySql分表设计,Java分表设计

一、前言

1-1、什么时候需要分表呢?

这个其实就很简单了,就是当表数据太大的时候,一个表里面存储不下,或者存储后影响使用(比如数据多的时候就影响查询效率)


1-2、分表的规则是什么呢?

一般来说我们都是根据数据量来分表的,数据存储是为了后面使用,所以我们表名也应该清楚明了。

我们可以根据数据量分为、天、月、年 (当然了,还可以细分,但是逻辑会相对复杂一些,原理都一样)


1-2-1、分表前后

这里以月和年进行举例

之前的表名之后的表名
pub_send_messagepub_send_message_2021_03
pub_send_message_batchpub_send_message_batch_2021

其实也很简单,就是在之前的表名后面加上规则。


1-2-2、其它

这里有有趣的事情

  • 我:你看看这样命名有没问没? pub_send_message_21_03
  • 大佬:小了,格局小了,你们公司难道不能存活80年以上嘛?

二、举例场景

这里举例一个短信中台的业务场景。

短信的发送1V1和1VN,也就是一条短信发送给一个人,一条短信发送给多个人。

每一条短信都是要先存到数据库,为了后面追溯,所以需要一个短信明细表,一个短信批次表。


三、实现分表功能


3-1、数据的增删改

之前我们插入数据的时候只需要写下面的sql

INSERT INTO pub_send_message (id,mobile) VALUES(#{id},#{mobile});

而现在的话,因为我们的表是按照月份区分的,所以再插入的时候我们需要明确我们的表名。

我们获取到当前年、月的时候,传递过去就好了,所以我们的sql改成这样。

INSERT INTO pub_send_message_${year}_${month} (id,mobile) VALUES(#{id},#{mobile});

注:这里需要区分一下 $ 和#的区别,$是字符串拼接,#是带引号的拼接。


3-2、数据的查询

因为我们查询的数据可能存在多张表里面,这样就很难的查询了。

  • 上面我们是按照月来区分的,所以我们可以规定一下,我们只查询本月数据
  • 我们可以规定下只查询近3个月的数据,这样我们可以使用union连接查询
  • 如果要以某个维度查询全部的数据,那么建议以这个维度建立一个报表(不可能全部的数据去union的)

3-3、自动创建表

比如上面的这个pub_send_message_2021_03表,每个月都会产生一张,我们不可能每个月自己去建,一来这样很麻烦,二来如果忘记了系统就会异常,所以我们要写一个定时任务或者脚本去自动生成表。


MySql查看表是否存在

  • work_order 数据库名
  • css_work_order_21表名
SELECT
	count(*) 
FROM
	information_schema.TABLES t 
WHERE
	t.TABLE_SCHEMA = 'work_order' 
	AND t.TABLE_NAME = 'css_work_order_21'

建表语句就不说了,Java定时任务或脚本见表也不说了


3-4、其它

这里说一个小的设计思路

如果我们之前的代码是这样写的

void add(PubSendMessage pubSendMessage);

<select id="add" parameterType="com.koron.mgdevops.shortmessage.bean.PubSendMessage">
    INSERT INTO pub_send_message (id,mobile) VALUES(#{id},#{mobile});
</select>

现在我们的操作都是要多传入yearmonth两个参数

方法一

void add(@Param("bean") PubSendMessage pubSendMessage,@Param("year") String year,@Param("month") String month);

<select id="add" parameterType="com.koron.mgdevops.shortmessage.bean.PubSendMessage">
    INSERT INTO pub_send_message_${year}_${month} (id,mobile) VALUES(#{bean.id},#{bean.mobile});
</select>

方法二

先让我们的PubSendMessage去继承一个新的实体,这样我们其它的接口和xml都不需要改变了

public  class PubSendMessage  extends TestBean2{}
public class TestBean2  {

    private String year;

    private String month;


    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String getMonth() {
        return month;
    }

    public void setMonth(String month) {
        this.month = month;
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值