MySQL的分表和分区介绍

在日常开发或维护中经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。

一、什么是分表:

分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。这些子表可以分布在同一块磁盘上,也可以在不同的机器上。

1、根据分表技术对海量数据的优化方式目前有2种方法:

1、垂直分割:把一个数据量很大的表,根据某个字段的属性或使用频繁程度分类拆分为多个表,一般电商数据库:用户表、订单表、支付系统等

2、水平分割:根据一列或者多列的值把数据行放到多个独立的表里,水平分表方式可以通过多个低配置主机整合起来,实现高性能。

3、两者的优缺点:

水平优点:拆分规则抽象好,JION操作基本可以数据库做,不存在单表大数据、高并发的性能瓶颈,应用端改造较少,提高系统的稳定性和负载能力

缺点:分片事务一致性难以解决,在MyCAT2.0之前MySQL5.7之前,还是数据弱XA。数据多次扩展难度维护量大,夸库JOIN性能差

垂直优点:拆分后业务清晰,拆分规则明确,系统之间整合或者拓展容易,数据库维护简单

缺点:部分业务无法使用JOIN,只能通过接口方式解决,提供系统能够复杂度,受每种业务不同的限制存在性能瓶颈,不容易数据扩展跟性能提高。

事务处理复杂,垂直切分后按照业务的分类将表分散到不同的库,会导致有些业务表过于庞大,存在单库读写与存储瓶颈。

二、什么是分区

分区就是把一张表的数据分成N多个区域,分区后,表面上还是一张表,但数据散列到多个位置根据数据量的大小,结合实际业务

1、分区方式有:

a、range分区:主要用于时间列分区、值范围,行数据基于一个给定连续分区的列值放入分区。如销售类的表,可以根据年来分区存放销售记录

b、list分区:面向离散的值,分区要指定的值,当插入指定的数据到指定分区表去,如指定某些值在特定分区里。

c、key分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

d、hash分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。

三、分区实例:

创建redundant格式

      如果表中存在主键或是唯一索引时,分区列必须是唯一索引的一个组成部分
唯一索引     
 create table t11(
      col1 int not null,
      col2 date not null,
      col3 int not null,
      col4 int not null,
      unique key (col1,col2))
      partition by hash(col1)
      partitions 4;
 哈希     
create table t121(
      col1 int not null,
      col2 date not null,
      col3 int not null,
      col4 int not null,
      unique key (col1,col2))
      partition by hash(year(col2))
      partitions 4;
主键
create table t31(
      col1 int not null,
      col2 date not null,
      col3 int not null,
      col4 int not null,
      primary key (col1,col2))
      partition by hash(col1)
      partitions 8;
主键和索引同时存在:
create table t41(
      col1 int not null,
      col2 date not null,
      col3 int not null,
      col4 int not null,
      unique key(col4),
      primary key (col1))
      partition by hash(col1)
      partitions 5;

      唯一索引可以允许是null值,分区列只要是唯一索引的一个组成部分,不需要整个唯一索引列都是分区列
create table t223332(
col1 int null,
col2 date null,
col3 int null,
col4 int null)
partition by hash(col3)
partitions 4;
    没有主键或唯一索引,可以指定任何一个列为分区列
create table t223332(
col1 int null,
col2 date null,
col3 int null,
col4 int null,
key(col4))
partition by hash(col3)
partitions 4;
    rang 分区:主要用于时间列分区,如销售类的表,可以根据年来分区存放销售记录
    定义:行数据基于一个给定连续分区的列值放入分区,
       id 是主键
    create table t3(
    id int)engine=innodb
    partition by range(id)(
    partition p0 values less than (10),
    partition p1 values less than (20)
 );
    查看数据文件
    t3.frm t.par
    insert into t select 9;
    insert into t select 10;
    insert into t select 15;
    查看分区状态
   use information_schema
    select * from PARITIONS where table_schema=‘‘test and table_name=‘t3‘\G;
    partition_method代表分区类型    
  当不满足分区条件的时候报错
  table has no partition for value 40
 alter table t add partition(partition p2 values less than maxalue);  
  主要用于时间列分区,如销售类的表,可以根据年来分区存放销售记录(year(date))取年的时间
    create table sales(
    money int not null,date datetime)engine=innodb
    partition by range (year(date))(
    partition p2008 values less than (2009),
     partition p2009 values less than (2010),
       partition p2010 values less than (2011)
       );
       insert into sales select 100,‘2008-01-01‘; 
      insert into sales select 100.‘2008-02-01‘; 
      insert into sales select 100.‘2008-01-02‘; 
      insert into sales select 100,‘2009-03-01‘; 
      insert into sales select 100,‘2010-01-01‘; 
     
 list 分区:面向离散的值,分区要指定的值,当插入指定的数据到指定分区表去,
    create table t_list (a int,b int)engine=innodb
    partition by list(b)(partition p0 values in(1,3,5,7,9),
    partition p1 values in (0,2,4,6,8));
    
      insert into  t4 select 1, 3;
      insert into  t4 select 1, 5;
      insert into  t4 select 1, 8;
      insert into  t4 select 1, 6;
      table has no partition for values10
      值得注意的是,LIST分区没有类似如“VALUES LESS THAN MAXVALUE”这样的包含其他值在内的定义。将要匹配的任何值都必须在值列表中找到。
    LIST分区除了能和RANGE分区结合起来生成一个复合的子分区,与HASH和KEY分区结合起来生成复合的子分区也是可能的。
      
      
  注意:innodb myisam区别
  在用insert插入多行数据的过程中遇到分区为定义的值,myisam、innodb存储引擎的处理完全不同,
  myisam 一条不成功,之前的成功值,会进入表中
  innodb只要一条不成功,所有都不成功
create table t(a int,b int)engine=myisam partition by list(b)(partition p0 values in (1,3,5,7,9),partition p1 values in (0,2,4,6,8));
insert into t values (1,2),(2,4),(6,19),(5,3);
insert into t values (1,2),(2,4),(6,19),(5,3);
ERROR 1526 (HY000): Table has no partition for value 19
select * from t;
+------+------+
| a    | b    |
+------+------+
|    1 |    2 |
|    2 |    4 |
+------+------+
2 rows in set (0.00 sec)

create table tt(a int,b int)engine=innodb partition by list(b)(partition p0 values in (1,3,5,7,9),partition p1 values in (0,2,4,6,8));
insert into tt values (1,2),(2,4),(6,19),(5,3);
insert into tt values (1,2),(2,4),(6,19),(5,3);
ERROR 1526 (HY000): Table has no partition for value 19
 select * from tt;
Empty set (0.00 sec)
      hash 分区:根据用户的表达式的返回值来进行分区,返回值不能是负数
      要在create table 语句上添加一个partition by hash(expr)句子,其中expr是一个返回一个整数的表达式,它可以仅仅是数字段类型为mysql整型的列名字
      后面在添加一个partitions num子句,num是一个非负数
      create table t_hash(a int,b date)engine=innodb
      partition by hash(YEAR(b))
      partitions 4;
      insert into t_hash select 1,‘2010-04-01‘;
     
      create table tt_hash(a int,b date)engine=innodb
      partition by hash (a)
      partitions 4;

      
      #######################################
      columns分区
      区别于其他分区,分区条件必须是整型,如果不是整型也应该需要通过函数将其转化为整型 columns分时是rang list分区的进化
      支持整型类型
      日期类型date datetime其余的日期类型不予支持
      字符串类型 char varcha binary  varbinary ,blok和text类型的不予支持
      create table tt_column_range(a int,b int)engine=innodb partition by range columns(a,b)(
      partition p0 values less than (0,10),
      partition p1 values less than (10,20),
      partition p2 values less than (20,30),
      partition p3 values less than (30,40),
      partition p4 values less than (40,50)
      );
      
      
     子分区:MYSQL数据库允许在rang和list的分区上再进行hask或者key子分区,
     create table ts(a int,b date)engine=innodb
     partition by range(year(b))
     subpartition by hash(to_days(b))
     subpartitions 3(
     partition p0 values less than (2013),     
       partition p0 values less than (2014),
       partition p1 values less than (2015)
  partition p2 values less than maxvalue);
 

create table ts(a int,b date
partition by range(year(b))
subpartition by hash(to_days(b))(
partition p0 values less than(2014)(
subpartition s0,
subpartition s1)

partition p1 values less than (2015)(
subpartition s2,
subpartition s3
)
partition p2 values less than maxvalue(
subpartition s4
subpartition s5
)
)
      
      
      
每个子分区必须包含分区的名字。  
子分区的名字唯一的。

分区中null值
create table t3(
    id int)engine=innodb
    partition by range(id)(
    partition p0 values less than (10),
    partition p1 values less than (20);
 );
 null值 放最左边的。
时间: 2024-10-09 22:10:13

MySQL的分表和分区介绍的相关文章

MySql分库分表与分区的区别和思考

一.分分合合 说过很多次,不要拘泥于某一个技术的一点,技术是相通的.重要的是编程思想,思想是最重要的.当数据量大的时候,需要具有分的思想去细化粒度.当数据量太碎片的时候,需要具有合的思想来粗化粒度. 1.1 分 很多技术都运用了分的编程思想,这里来举几个例子,这些都是分的思想 集中式服务发展到分布式服务 从Collections.synchronizedMap(x)到1.7ConcurrentHashMap再到1.8ConcurrentHashMap,细化锁的粒度的同时依旧保证线程安全 从Ato

Mysql分表和分区的区别、分库分表介绍与区别

分表和分区的区别: 一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看:mysql分表的3种方法 什么是分区,分区呢就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,具体请参考mysql分区功能详细介绍,以及实例 二,mysql分表和分区有什么区别呢 1,实现方式上 a),mysql的分表是真正的分表,一张表分成很多表后,每一个小表都是完正的一张表,都对应三个文件,一个.MYD数据文件,.MYI索引文件,.frm表

MySQL数据库分表分区(一)(转)

面对当今大数据存储,设想当mysql中一个表的总记录超过1000W,会出现性能的大幅度下降吗? 答案是肯定的,一个表的总记录超过1000W,在操作系统层面检索也是效率非常低的 解决方案: 目前针对海量数据的优化有两种方法: 1.大表拆小表的方式(主要有分表和分区两者技术) (1)分表技术 垂直分割 优势:降低高并发情况下,对于表的锁定. 不足:对于单表来说,随着数据库的记录增多,读写压力将进一步增大. 水平分割 如果单表的IO压力大,可以考虑用水平分割,其原理就是通过hash算法,将一张表分为N

mysql数据库分表分区

防伪码:博观而约取,厚积而薄发 为什么要分表和分区? 我们的数据库数据越来越大,随之而来的是单个表中数据太多.以至于查询书读变慢,而且 由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈. mysql 中有一种机制是表锁定和行锁定,是为了保证数据的完整性.表锁定表示你们都不能 对这张表进行操作,必须等我对表操作完才行.行锁定也一样,别的 sql 必须等我对这条数 据操作完了,才能对这条数据进行操作.当出现这种情况时,我们可以考虑分表或分区. 1.分表 什么是分表? 分表是将一个大表按

mysql数据库为什么要分表和分区?

一般下载的源码都带了MySQL数据库的,做个真正意义上的网站没数据库肯定不行. 数据库主要存放用户信息(注册用户名密码,分组,等级等),配置信息(管理权限配置,模板配置等),内容链接(html ,图片,声音,视频等等的路径).那mysql数据库为什么要分表和分区? 为什么要分表和分区? 我们的数据库数据越来越大,随之而来的是单个表中数据太多.以至于查询书读变慢,而且 由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈. mysql 中有一种机制是表锁定和行锁定,是为了保证数据的完整性

mysql分表和分区简述

1)分表目的:提升对海量数据的进行存取操作的效率选择合适的分表策略,确定分表策略后,当进行数据存取操作时,需求确定要到那张表里去查询数据分表字段:互联网的系统使用用户id字段数据是放到哪个表:分表的字段%分表的数量策略:根据范围分区(表ID 1~200 db1 表ID 201~200 db2 表ID m~n dbn) 范围应该连续但是不连续,使用PAPRTION BY RANGE VALUES LESS THAN关键字不使用COLUMNS关键字时,RANGE中必须为整数字段名或返回确定整数字段的

MySQL分库分表工具oneproxy安装说明

                    oneproxy数据库中间件说明 #wget http://www.onexsoft.com/software/oneproxy-rhel5-linux64-v6.0.0-ga.tar.gz #tar -zxvf oneproxy-rhel5-linux64-v6.0.0-ga.tar.gz  -C /usr/local/ # cd /usr/local/oneproxy/ 1.指定中间件启动的shell脚本和启动文件的程序目录位置 # sed -i 's

MySQL数据库分表分表区

为什么要分表和分区? 我们的数据库数据越来越大,随之而来的是单个表中数据太多.以至于查询书读变慢,而且由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈. mysql中有一种机制是表锁定和行锁定,是为了保证数据的完整性.表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行.行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作.当出现这种情况时,我们可以考虑分表或分区. 1.分表 什么是分表? 分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体

OneProxy实现MySQL分库分表

OneProxy实现MySQL分库分表 简介 Part1:写在最前 随着网站的壮大,MySQL数据库架构一般会经历一个过程: 当我们数据量比较小的时候,一台单实例数据库足矣.等我们数据量增大的时候,我们会采用一主多从的数据库架构来降低我们的读写io.当我们某张业务表达到几百万上千万甚至上亿时,就应该去进行分表处理.本文演示OneProxy对数据库实现分表处理,对前端应用是透明的. Part2:环境简介 HE1:192.168.1.248 Master1 HE3:192.168.1.250 Mas