数据库分区和分表的区别

数据库分区和分表的区别,第1张

分区、分表、分库的详细理解

一、什么是分区、分表、分库

分区

就是把一张表的数据分成N个区块,在逻辑上看最终只是一张表,但底层是由N个物理区块组成的

分表

就是把一张表按一定的规则分解成N个具有独立存储空间的实体表。系统读写时需要根据定义好的规则得到对应的字表明,然后操作它。

分库

一旦分表,一个库中的表会越来越多

将整个数据库比作图书馆,一张表就是一本书。当要在一本书中查找某项内容时,如果不分章节,查找的效率将会下降。而同理,在数据库中就是分区。

二、常用的单机数据库的瓶颈

问题描述

单个表数据量越大,读写锁,插入操作重新建立索引效率越低。

单个库数据量太大(一个数据库数据量到就是极限)

单个数据库服务器压力过大

读写速度遇到瓶颈(并发量几百)

三、分区

什么时候考虑使用分区?

一张表的查询速度已经慢到影响使用的时候。

sql经过优化

数据量大

表中的数据是分段的

对数据的操作往往只涉及一部分数据,而不是所有的数据

分区解决的问题

主要可以提升查询效率

分区的实现方式(简单)

mysql5 开始支持分区功能

四、分表

什么时候考虑分表?

一张表的查询速度已经慢到影响使用的时候。

sql经过优化

数据量大

当频繁插入或者联合查询时,速度变慢

分表解决的问题

分表后,单表的并发能力提高了,磁盘I/O性能也提高了,写操作效率提高了

查询一次的时间短了

数据分布在不同的文件,磁盘I/O性能提高

读写锁影响的数据量变小

插入数据库需要重新建立索引的数据减少

分表的实现方式(复杂)

需要业务系统配合迁移升级,工作量较大

分区和分表的区别与联系

分区和分表的目的都是减少数据库的负担,提高表的增删改查效率。

分区只是一张表中的数据的存储位置发生改变,分表是将一张表分成多张表。

当访问量大,且表数据比较大时,两种方式可以互相配合使用。

当访问量不大,但表数据比较多时,可以只进行分区。

常见分区分表的规则策略(类似)

Range(范围)

Hash(哈希)

按照时间拆分

Hash之后按照分表个数取模

在认证库中保存数据库配置,就是建立一个DB,这个DB单独保存user_id到DB的映射关系

我们知道可以将一个海量记录的

MySQL

大表根据主键、时间字段,条件字段等分成若干个表甚至保存在若干服务器中。

唯一的问题就是跨服务器批量查询麻烦,只能通过应用程序来解决。谈谈在Java中的解决思路。其他语言原理类似。

这里说的分表不是

MySQL

5.1

partition,而是人为把一个表分开存在若干表或不同的服务器。

1.

应用程序级别实现

见示意图

electThreadManager

分表数据查询管理器

它为分表的每个database

or

server

建立一个

thread

pool

addTask()

-

添加任务

stopTask()

-

停止任务

getResult()

-

获取执行结果

最快的执行时间

=

最慢的

MySQL

节点查询消耗时间

最慢的执行时间

=

超时时间

某个

ThreadPool

忙时候处理流程

1.

假如

ThreadPoolN

非常忙,(也意味

DB

N

非常忙);

2.

新的查询任务到来,addTask(),

新的任务的一个thread加到ThreadPoolN任务排队中

3.

外层应用已经获得其他

thread

返回结果,继续等待

4.

外层应用等待超时的时间到,调用

stopTask()

设置该任务全部

thread

中的停止标志,

外层应用返回。

5.

若干时间后,ThreadPoolN取到该排队

Thread,

因为设置了停止位,线程直接运行完成。

2.

JDBC

层实现

做一个

JDBC

Driver

的包装,拦截

PreparedStatement,

Statement

executeQuery()

然后调用

SelectThreadManager

完成

3.

MySQL

partition

MySQL

5.1

partition

功能由于单张表的数据跨文件,批量查询时候同样存在上述问题,不过它是在

MySQL

内部实现的,不需要外部调用者关心。其查询实现的原理应该大致类似。

partition

只解决了

IO

的瓶颈,并不能解决

CPU

计算的瓶颈,因此无法代替传统的手工分表方式。

一、分库分表的必要性

分库分表技术的使用,主要是数据库产生了瓶颈,如单库的并发访问或单表的查询都超出了阈值。对系统使用造成一定的影响,不得已而产生的技术。

通过分库分表技术来解决此类问题,但正因为使用此技术,会产生ACID一系列的问题,各类中间件解决此类问题各有各的优势。

提示:如场景无必要,千万不要使用分库分表。

二、分库分表的思路

1、垂直区分

垂直分库:从业务角度,一个库分成多个库,如把订单和用户信息分成两个库来存储。这样的好处就是可以微服务了。每块的业务单独部署,互不影响,通过接口去调用。

垂直分表:把大表分成多个小表,如热点数据和非热点数据分开,提高查询速度。

2、水平区分

水平分表:同一业务如数据量大了以后,根据一定的规则分为不同的表进行存储。

水平分库:如订单分成多个库存储,分解服务器压力。

以上一般来说,垂直分库和水平分表用的会多些。

三、分库分表的原理分析

分库分表常用的方案:Hash取模方案和range范围方案;

路由算法为最主要的算法,指得是把路由的Key按照指定的算法进行存放;

1、Hash取模方案

根据取余分配到不同的表里。要根据实际情况确认模的大小。此方案由于平均分配,不存在热点问题,但数据迁移很复杂。

2、Range范围方案

range根据范围进行划分,如日期,大小。此方案不存在数据迁移,但存在热点问题。

四、分库分表的技术选型

1、技术选型

解决方案主要分为4种:MySQL的分区技术、NoSql、NewSQL、MySQL的分库分表。

(1)mysql分区技术:把一张表存放在不同存储文件。由于无法负载,使用较少。

(2)NoSQL(如MongoDB):如是订单等比较重要数据,强关联关系,需约束一致性,不太适应。

(3)NewSql(具有NoSQL对海量数据的存储管理能力,还保持了传统数据库支持ACID和SQL等特性):如TiDB可满足需求。

(4)MySQL的分库分表:如使用mysql,此种方案为主流方式。

2、中间件

解决此类问题的中间件主要为:Proxy模式、Client模式。

(1)Proxy模式

(2)Client模式

把分库分表相关逻辑存放在客户端,一版客户端的应用会引用一个jar,然后再jar中处理SQL组合、数据库路由、执行结果合并等相关功能。

(3)中间件的比较

由于Client模式少了一层,运维方便,相对来说容易些。

五、分库分表的实践

根据容量(当前容量和增长量)评估分库或分表个数 ->选key(均匀)->分表规则(hash或range等)->执行(一般双写)->扩容问题(尽量减少数据的移动)。

在这里我们选用中间件share-jdbc。

1、引入maven依赖

2、spring boot规则配置

行表达式标识符可以使用${...}或$->{...},但前者与Spring本身的属性文件占位符冲突,因此在Spring环境中使用行表达式标识符建议使用$->{...}。

3、创建DataSource

通过ShardingDataSourceFactory工厂和规则配置对象获取ShardingDataSource,ShardingDataSource实现自JDBC的标准接口DataSource。然后即可通过DataSource选择使用原生JDBC开发,或者使用JPA, MyBatis等ORM工具。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/162260.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-24
下一篇2023-03-24

发表评论

登录后才能评论

评论列表(0条)

    保存