当前位置:数据库 > > 正文

mysql分库分表视图(MySQL分库分表与分区的入门指南)

时间:2021-10-12 00:24:53类别:数据库

mysql分库分表视图

MySQL分库分表与分区的入门指南

前言

关系型数据库比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限,当数据量和并发量起来之后,就必须对数据库进行切分了。

数据切分(sharding)的手段就是分库分表。分库分表有两方面,可能是光分库不分表,也可能是光分表不分库。

数据库分布式的核心内容无非就是数据切分,以及切分后对数据的定位、整合。

为什么要分库分表

分表

单表数据量太大时,会严重影响sql执行的性能。一般单表到达几百万的时候,性能就会相对差一些了,这时就得分表了。

分表就是把一个表的数据放到多个表中,然后查询的时候就查一个表。比如按照项目id来分表:将固定数量的项目数据放在一个表中,这样就可以控制每个表的数据量在可控的范围内。

分库

根据经验来讲,一个库最多支持到并发2000时就需要扩容了,而且一个健康的单库并发值最好保持在1000左右。那么你可以将一个库的数据拆分到多个库中,访问的时候就访问一个库好了。

这就是所谓的分库分表,为啥要分库分表?

如何分库分表

直接看图:

mysql分库分表视图(MySQL分库分表与分区的入门指南)

对于垂直拆分,建议最好在系统设计之初做好表设计,避免垂直分表。

水平拆分可以按照range来分,或是按照某个字段hash。按照range来分,好处在于扩容简单,准备好新的表或库就可以了。但是容易产生热点问题,实际使用时要结合业务场景来看。按照hash来分,好处在于可以平均分配每个库或表的请求压力,缺点是扩容麻烦,之前的数据要rehash,存在一个数据迁移的过程。

分库分表带来的问题

分库分表能有效地缓解单机和单库带来的网络io、硬件资源、连接数的压力。但也带来了一些问题。

数据迁移

数据迁移介绍两种方案。

一个最low的方案,就是系统停机一段时间,用实现写好的导数据的工具跑一遍把单独单表的数据独出来,写到分库分表里面去。

第二个方案听起来就比较靠谱了,双写迁移方案。在线上系统里,之前所有写数据的地方,增删改操作,除了对旧库增删改,再加上对新库的增删改,这就是所谓的双写。然后系统部署之后,把方案一里的导数据工具跑起来,读老库写新库。写的时候要根据gmt_modified这类字段判断这条数据最后修改的时间,除非是读出来新库没有,或是比新库数据新才会写。简单来说就是不允许用老数据覆盖新数据。

写完一轮之后,有可能还是存在不一致,那么就程序自动新一轮校验,对比新老库每个表的每条数据,接着如果有不一样的,就针对那些不一样的,从老库读数据再次写。反复循环直到数据完全一致。

中间件

分库分表的中间件比较常见的有:

综上,现在可以考虑使用的就是sharding-jdbc和mycat。

sharding-jdbc这种client层方案的有点在于不用部署,运维成本低,不需要代理层的二次转发,性能高。缺点是有耦合性。
mycat这种proxy层方案的缺点在于需要部署,自己运维一套中间件,运维成本高,但是好处在于对项目是透明的。

mysql分区(不建议使用)

这里介绍分区主要是防止和切分、分库分表等概念混淆。
mysql从5.1版本开始支持分区(partition)的功能。分区指根据一定的规则,数据库把一个表分解成多个更小的、更容易管理的部分。就访问数据库的应用而言,逻辑上只有一个表或一个索引,但是实际上这个表可能由多个物理分区组成,即对应用是透明的。
mysql分区引入了分区键的概念,采取分治法,有利于管理非常大的表。分区键用于根据某个区间值、特定值列表或hash函数执行数据的聚集,让数据根据规则分布在不同的分区中。mysql 5.7中可用的分区类型主要有以下6种:

这里举一list分区的例子:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • create table orders_list (
  •   id int auto_increment,
  •   customer_surname varchar(30),
  •   store_id int,
  •   salesperson_id int,
  •   order_date date,
  •   note varchar(500),
  •   index idx (id)
  • ) engine = innodb
  •   partition by list(store_id) (
  •   partition p1
  •   values in (1, 3, 4, 17)
  •   index directory = '/var/orders/district1'
  •   data directory = '/var/orders/district1',
  •   partition p2
  •   values in (2, 12, 14)
  •   index directory = '/var/orders/district2'
  •   data directory = '/var/orders/district2',
  •   partition p3
  •   values in (6, 8, 20)
  •   index directory = '/var/orders/district3'
  •   data directory = '/var/orders/district3',
  •   partition p4
  •   values in (5, 7, 9, 11, 16)
  •   index directory = '/var/orders/district4'
  •   data directory = '/var/orders/district4',
  •   partition p5
  •   values in (10, 13, 15, 18)
  •   index directory = '/var/orders/district5'
  •   data directory = '/var/orders/district5'
  • );
  • 分区的优点:

    总结

    到此这篇关于mysql分库分表与分区的文章就介绍到这了,更多相关mysql分库分表分区内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!

    原文链接:https://juejin.cn/post/6953160786281775111

    上一篇下一篇

    猜您喜欢

    热门推荐