赞
踩
mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的 datadir来查看),一张表主要对应着三个文件(8.0对应两个,往期版本三个)一个是frm存放表结构的,一 个是myd存放表数据的,一个是myi存表索引的(innodb同理)。
如果一张表的数据量太大的话,那么myd,myi就会变的很大,查找数据就会变的很慢,这个时候我们可以利 用mysql的分区功能,在物理上将这一张表对应的三个文件,分割成许多个小块,这样呢,我们查找一条数 据时,就不用全部查找了,只要知道这条数据在哪一块,然后在那一块找就行了。如果表的数据太大,可 能一个磁盘放不下,这个时候,我们可以把数据分配到不同的磁盘里面去。
表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只 有一张表,但是底层却是由多个物理分区组成。
表分区的优点
表分区的限制
说明:在MySQL5.1版本中,RANGE,LIST ,HASH分区要求分区键必须是INT类型,或者通过表达式返回INT类 型。但KEY分区的时候,可以使用其他类型的列(BLOB,TEXT类型除外)作为分区键。
range分区使用values less than 操作符来进行定义, 把连续且不相互重叠的字段分配给分区,命令如下。
create table emp( `no` varchar(20) not null, `name` varchar(20), deptno int, birthdate date, salary int ) partition by range(salary) ( partition p1 values less than(1000), partition p2 values less than(5000), partition p3 values less than(10000) ); insert into emp values('001', 'shineyork', 10, '2019-10-10', 5000); insert into emp values('002', 'keke', 20, '2019-10-10', 1500); insert into emp values('003', 'a', 10, '2019-10-10', 10500); insert into emp values('004', 'n', 20, '2019-10-10', 1000); insert into emp values('004', 'c', 20, '2019-10-10', 6000);
如上的方式就是把数据根据salary的value进行划分,区分到不同的表区中;而这其中partition by range的语 法类似于“switch…case”的语法,如果salary小余5000就会在p1中。。。
mysql> insert into emp values('003', 'a', 10, '2019-10-10', 10500);
ERROR 1526 (HY000): Table has no partition for value 10500
而上面的insert中因为10500不在这个范围类所以会产生问题,解决这个问题的办法就是在其后加入“partition p4 values less than maxvalue” 语法
create table emp(
`no` varchar(20) not null,
`name` varchar(20),
deptno int,
birthdate date,
salary int
)
partition by range(salary) (
partition p1 values less than(1000),
partition p2 values less than(5000),
partition p3 values less than(10000),
partition p4 values less than maxvalue
)
查询分区之后某一个区中的数据
select * from emp partition (p3);
在range中也可以使用MySQL的系统函数,比如根据年龄进行区分
create table emp(
`no` varchar(20) not null,
`name` varchar(20),
deptno int,
birthdate date,
salary int
)
partition by range(year(birthdate)) (
partition p1 values less than(1990),
partition p2 values less than(2000),
partition p3 values less than(2010),
partition p4 values less than maxvalue
)
list分区类似于range分区,区别在于list中的每个分区的定义和选择基于某列的值从属于一个集合,而range 分区是属于一个连续区间值得集合。
create table emp( `no` varchar(20) not null, `name` varchar(20), deptno int, birthdate date, salary int ) partition by list(deptno) ( partition p1 values in (10,20,30), partition p2 values in (1,2,3), partition p4 values in (4,40) ); insert into emp values('001', 'shineyork', 1, '2019-10-10', 5000); insert into emp values('002', 'keke', 20, '2019-10-10', 1500); insert into emp values('003', 'a', 10, '2019-10-10', 10500); insert into emp values('004', 'n', 40, '2019-10-10', 1000); insert into emp values('005', 'c', 6, '2019-10-10', 6000); mysql> insert into emp values('005', 'c', 6, '2019-10-10', 6000); ERROR 1526 (HY000): Table has no partition for value 6
HASH分区是基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的 列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。 HASH分区主要用来 确保数据在预先确定数目的分区中平均分布。 在RANGE和LIST分区中,必须明确指定一个给定的列值或列 值集合应该保存在哪个分区中;而在HASH分区中,MySOL自动完成这些工作,用户所要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。
create table emp(
`no` varchar(20) not null,
`name` varchar(20),
deptno int,
birthdate date,
salary int
)
partition by hash(year(birthdate)) partitions 4;
类似于hash分区,区别在于key分区只支持计算依赖或多列,且MySQL服务器其自身的哈希函数,这些函数 是基于password()一样的运算规则
create table emp(
`no` varchar(20) not null,
`name` varchar(20),
deptno int,
birthdate date,
salary int
)
partition by key(year(birthdate)) partitions 4;
作为一个数据库,作为数据库中的一张表,随着用户的增多随着时间的推移,总有一天,数据量会大到一 个难以处理的地步。这时仅仅一张表的数据就已经超过了千万,无论是查询还是修改,对于它的操作都会 很耗时,这时就需要进行数据库切分的操作了。对于一个大型的互联网应用,海量数据的存储和访问成为了系统设计的瓶颈问题,对于系统的稳定性和扩展性造成了极大的问题。通过数据切分来提高网站性能, 横向扩展数据层已经成为架构研发人员首选的方式。
问题描述
何为切分?
简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主 机)上面,以达到分散单台设备负载的效果。 数据的切分(Sharding)根据其切分规则的类型,可以分为 两种切分模式。一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称 之为数 据的垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种 条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。
垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很 小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的 数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。
水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库 中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一 些。
相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表 中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某 些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。
拆分数据就需要定义分片规则。关系型数据库是行列的二维模型,拆分的第一原则是找到拆分维度。比 如:从会员的角度来分析,商户订单交易类系统中查询会员某天某月某个订单,那么就需要按照会员结合 日期来拆分,不同的数据按照会员 ID 做分组,这样所有的数据查询 join 都会在单库内解决;如果从商户的 角度来 讲,要查询某个商家某天所有的订单数,就需要按照商户 ID 做拆分;但是如果系统既想按会员拆 分,又想按商家数据,则会有一定的困难。如何找到合适的分片规则需要综合考虑衡量。
几种典型的分片规则包括:
既然数据做了拆分有优点也就有缺点。
优点:
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不 同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下图
系统被切分成了,用户,订单交易,支付几个模块。 一个架构设计较好的应用系统,其总体功能肯定是由 很多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一个或者多个表。而在架 构设计中,各个功能模块相互之间的交互点越统一越少,系统的耦合度就越低,系统各个模块的维护性以 及扩展 性也就越好。这样的系统,实现数据的垂直切分也就越容易。但是往往系统之有些表难以做到完全 的独立,存在这扩库 join 的情况,对于这类的表,就需要去做平衡,是数据库让步业务,共用一个数据 源,还是分成多个库,业务之间通过接口来做调用。在系统初期,数据量比较少,或者资源有限的情况 下,会选择共用数 据源,但是当数据发展到了一定的规模,负载很大的情况,就需要必须去做分割。
一般来讲业务存在着复杂 join 的场景是难以切分的,往往业务独立的易于切分。如何切分,切分到何种程 度是考验技术架构的一个难题。
优点:
由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。