当前位置: 首页 > news >正文

mysql简单分表_mysql分表场景分析与简单分表操作

为什么要分表

首先要知道什么情况下,才需要分表个人觉得单表记录条数达到百万到千万级别时就要使用分表了,分表的目的就在于此,减小数据库的负担,缩短查询时间.

表分割有两种方式:

1水平分割:根据一列或多列数据的值把数据行放到两个独立的表中。

水平分割通常在下面的情况下使用:

表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高查询速度。

表中的数据本来就有独立性,例如表中分别记录各个地区的数据或不同时期的数据,特别是有些数据常用,而另外一些数据不常用。

需要把数据存放到多个介质上。

水平分割会给应用增加复杂度,它通常在查询时需要多个表名,查询所有数据需要union操作。在许多数据库应用中,这种复杂性会超过它带来的优点,因为只要索引关键字不大,则在索引用于查询时,表中增加两到三倍数据量,查询时也就增加读一个索引层的磁盘次数。

2垂直分割:把主码和一些列放到一个表,然后把主码和另外的列放到另一个表中。

如果一个表中某些列常用,而另外一些列不常用,则可以采用垂直分割,另外垂直分割可以使得数据行变小,一个数据页就能存放更多的数据,在查询时就会减少I/O次数。 其缺点是需要管理冗余列,查询所有数据需要join操作。

场景案例:

博客系统

垂直分割:

文章标题,作者,分类,创建时间等,是变化频率慢,查询次数多,而且最好有很好的实时性的数据,我们把它叫做冷数据。

而博客的浏览量,回复数等,类似的统计信息,或者别的变化频率比较高的数据,我们把它叫做活跃数据。

所以,在进行数据库结构设计的时候,就应该考虑分表,首先是纵向分表的处理。

这样纵向分表后:

首先存储引擎的使用不同,冷数据使用MyIsam 可以有更好的查询数据。活跃数据,可以使用Innodb ,可以有更好的更新速度。

其次,对冷数据进行更多的从库配置,因为更多的操作是查询,这样来加快查询速度。对热数据,可以相对有更多的主库的横向分表处理。

其实,对于一些特殊的活跃数据,也可以考虑使用memcache ,redis之类的缓存,等累计到一定量再去更新数据库.

水平分割:

当博客的量达到很大时候,就应该采取横向分割来降低每个单表的压力,来提升性能。

例如博客的冷数据表,假如分为100个表,当同时有100万个用户在浏览时,如果是单表的话,会进行100万次请求,而现在分表后,就可能是每个表进行1万个数据的请求(因为,不可能绝对的平均,只是假设),这样压力就降低了很多很多。

使用Merge存储引擎展示水平分表实例:

查看mysql的存储引擎

mysql> show engines \G;

现实场景模拟

第一步: 创建表member

DROP table IF EXISTSmember;

create tablemember(

id bigint auto_increment primary key,

name varchar(20),

sex tinyint not null default '0')ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

第二步:创建存储过程,插入百万数据

48304ba5e6f9fe08f3fa1abda7d326ab.png

#如果存在已定义的存储过程inserts,删除掉

drop procedure IF EXISTSinserts;

#自定义结束符

delimiter //#创建存储过程

create procedureinserts()

begin

DECLARE i int;

set i = 1;

WHILE(i <= 10) DO

insert into member(name,sex) values(concat('name',i),i%2);

SET i = i+1;

END WHILE;

end;

#使用自定义结束符结束存储过程定义

//#还原结束符为;

delimiter ;

#调用存储过程

call inserts();

48304ba5e6f9fe08f3fa1abda7d326ab.png

MySQL的语法默认使用分号";"作为一条SQL语句结束的标志.可以使用delimiter命令将其修改成其他符号,如:"delimiter //" 表示以//作为提交符号.

为了演示分表,所以实例中插入10条数据模拟.

第三步:创建分表

48304ba5e6f9fe08f3fa1abda7d326ab.png

#分表1#

DROP table IF EXISTStb_member1;

create tabletb_member1(

id bigint primary keyauto_increment ,

name varchar(20),

sex tinyint not null default '0')ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

#分表2#

DROP table IF EXISTStb_member2;

#复制表1

create table tb_member2 like tb_member1;

48304ba5e6f9fe08f3fa1abda7d326ab.png

第四步:创建主表,这里主表的定义与要分的目标表有不同

48304ba5e6f9fe08f3fa1abda7d326ab.png

#主表#

DROP table IF EXISTStb_member;

create tabletb_member(

id bigintauto_increment ,

name varchar(20),

sex tinyint not null default '0',

INDEX(id)

)ENGINE=MERGE UNION=(tb_member1,tb_member2) INSERT_METHOD=LAST AUTO_INCREMENT=1 ;

48304ba5e6f9fe08f3fa1abda7d326ab.png

查询tb_member表的索引信息

mysql> show index from tb_member \G;

第五步:将目标表数据分到两个分表中去

48304ba5e6f9fe08f3fa1abda7d326ab.png

INSERT INTOtb_member1(tb_member1.id,tb_member1.name,tb_member1.sex)

SELECTmember.id,member.name,member.sex

FROM member where member.id%2=0;

INSERT INTOtb_member2(tb_member2.id,tb_member2.name,tb_member2.sex)

SELECTmember.id,member.name,member.sex

FROM member where member.id%2=1 ;

48304ba5e6f9fe08f3fa1abda7d326ab.png

当然实际场景根据需要进行唯一标识操作,取hash啊什么的等等,这里只使用简单去求模分表.

第六步: 查看分表数据

9dc487d5d367f275391c24419fbfa756.png

960001271b8820b92ab3666aa65f41ff.png

第七步: 查看总表数据

569d84e35b6a03609f953fe4b81f7cfa.png

这样就把表member中的数据分开了, 分成的表组为 tb_member为主表,tb_member1与tb_member2为分表.分表后,数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。

对于merge表,需要注意的是

1. 每个子表的结构必须一致,主表和子表的结构需要一致,

2. 每个子表的索引在merge表中都会存在,所以在merge表中不能根据该索引进行唯一性检索。

3. 子表需要是MyISAM引擎

4. REPLACE在merge表中不会工作

5. AUTO_INCREMENT 不会按照你所期望的方式工作

创建Mysql Merge表的参数 INSERT_METHOD有几个参数 。

LAST  如果你执行insert 指令来操作merge表时,插入操作会把数据添加到最后一个子表中。

FIRST  同理,执行插入数据时会把数据添加到第一个子表中。

相关文章:

  • vue 条件渲染与列表渲染
  • vue select清空_Vue+Webpack开发可复用的单页面富应用教程(技巧篇)
  • 两个同级div等高布局
  • cant connect to local mysql_Can't connect to local MySQL server through socket
  • jQuery的切换函数(hover,toggle)
  • mysql锁怎么控制并发_Mysql并发控制-锁
  • yii的ActionForm组件
  • java调用python爬虫_Java调用Python爬虫
  • 移动端如何用swiper实现导航栏效果
  • mysql undo_mysql 的undo 表空间
  • linux 后台开发类常见问题及知识点
  • mysql无法存 x_mySQL如果X Y不保存信息
  • mysql查询语句能用吗_基于mysql查询语句的使用详解
  • C语言程序设计第四次作业——选择结构(2)
  • 数组不能以什么形式参与运算_EXCEL知识:数组运算是什么?
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • Angular数据绑定机制
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • Java 多线程编程之:notify 和 wait 用法
  • Koa2 之文件上传下载
  • Redash本地开发环境搭建
  • spring security oauth2 password授权模式
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • Vue2.x学习三:事件处理生命周期钩子
  • 机器学习 vs. 深度学习
  • 基于Android乐音识别(2)
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 使用 QuickBI 搭建酷炫可视化分析
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # 数论-逆元
  • #{} 和 ${}区别
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Python第六天)文件处理
  • (多级缓存)多级缓存
  • (二)WCF的Binding模型
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (论文阅读11/100)Fast R-CNN
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET 8.0 发布到 IIS
  • .net 托管代码与非托管代码
  • .net6 webapi log4net完整配置使用流程
  • .NET大文件上传知识整理
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • ??在JSP中,java和JavaScript如何交互?
  • @RestController注解的使用
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • []指针
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)