项目开发中,我们的数据库数据越来越大,随之而来的是单个表中数据太多。以至于查询书读变慢,而且由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈。

当出现这种情况时,我们可以考虑分表,即将单个数据库表进行拆分,拆分成多个数据表,然后用户访问的时候,根据一定的算法,让用户访问不同的表,这样数据分散到多个数据表中,减少了单个数据表的访问压力。提升了数据库访问性能。

我们可以进行简单的设想:现在有一个表products存储产品信息,现在有100万用户在线访问,就要进行至少100万次请求,现在我们如果将它分成100个表即products0~~products99,那么利用一定的算法我们就分担了单个表的访问压力,每个表只有1万个请求(当然,这是理想情况下!)

实现mysql 分表的关键在于:设计良好的算法来确定"什么时候情况下访问什么(哪个)表"。

下面我们先来实现一个简单的mysql分表演示:这里使用MERGE分表法

1,创建一个完整表存储着所有的成员信息

create table member(
id bigint auto_increment primary key,
name varchar(20),
sex tinyint not null default '0'
)engine=myisam default charset=utf8 auto_increment=1;

加入点数据:

insert into member(id,name,sex) values (1,'jacson','0');

insert into member(name,sex) select name,sex from member;

第二条语句多执行几次就有了很多数据。

2,下面我们进行分表:这里我们分两个表tb_member1,tb_member2

DROP table IF EXISTS tb_member1;
create table tb_member1(
id bigint primary key auto_increment ,
name varchar(20),
sex tinyint not null default '0'
)ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; DROP table IF EXISTS tb_member2;
create table tb_member2(
id bigint primary key auto_increment ,
name varchar(20),
sex tinyint not null default '0'
)ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
//创建tb_member2也可以用下面的语句 create table tb_member2 like tb_member1;

3.创建主表tb_member

DROP table IF EXISTS tb_member;
create table tb_member(
id bigint primary key auto_increment ,
name varchar(20),
sex tinyint not null default '0'
)ENGINE=MERGE UNION=(tb_member1,tb_member2) INSERT_METHOD=LAST CHARSET=utf8 AUTO_INCREMENT=1 ;
4,接下来,我们把数据分到两个分表中去:

insert into tb_member1(id,name,sex) select id,name,sex from member where id%2=0;

insert into tb_member2(id,name,sex) select id,name,sex from member where id%2=1;

查看一下主表的数据:select * from tb_member;

注意:总表只是一个外壳,存取数据发生在一个一个的分表里面。

ps:创建主表时可能会出现下面的错误:

ERROR 1168 (HY000): Unable to open underlying table which is differently defined
or of non-MyISAM type or doesn't exist

若遇到上面这种错误,一般从两方面来排查:(从这两方面一般可以解决这个问题,本人也遇到了。)

  1,查看上面的分表数据库引擎是不是MyISAM.

  2,查看分表与指标的字段定义是否一致。

分表的大概过程和步骤就是这样的,下面我们来看看分表的算法实现:

假设现在有一个应用系统可能会有100亿的用户量,另外一个表一般存储量在不超过100万的时候基本能保持良好性能,计算下来,我们需要1万张表,即分表为1万个表。

我们可以设计成:user_0~user_9999

在用户表里面我们有唯一的标示是用户id,我们尅设计一个小算法来实现用户id与访问表名的对应:

function getTable($id)

{

return 'user_'.sprintf('%d',($id >>20));

}

解释一下:($id >> 20)表示将向右移位20位,(向右移动一位标示减少一半),printf('%d',$data)标示将数据按照十进制输出。

即id为1~1048575(2的20次幂-1)时均访问user_0,1048576~2097152时访问user_1,以此类推.....

那么问题来了,如果用户更多怎么办,现在需要一个可扩展的方法:

function getTable($id,$bit,$seed){
   return 'user_'.sprintf('%0{$bit}d',($id >> $seed));
}
其中:$id为用户id,$bit标示表后缀的位数,$seed表示要移位的位数即:单个表能存储的记录条数。
这样就可以任意分表了。
 
 
总结:
     其实上面我们介绍的是水平分表的实施方法,还存在另一种方法叫做:垂直分表
     垂直分表:
      举例说明,在一个博客系统中,文章标题,作者,分类,创建时间等,是变化频率慢,查询次数多,而且最好有很好的实时性的数据,我们把它叫做冷数据。
    而博客的浏览量,回复数等,类似的统计信息,或者别的变化频率比较高的数据,我们把它叫做活跃数据。
       我们进行纵向分表后:
      1,存储引擎的使用不同,冷数据使用MyIsam 可以有更好的查询数据。活跃数据,可以使用Innodb ,可以有更好的更新速度。
      2,对冷数据进行更多的从库配置,因为更多的操作是查询,这样来加快查询速度。对热数据,可以相对有更多的主库的横向分表处理。
      3,对于一些特殊的活跃数据,也可以考虑使用memcache ,redis之类的缓存,等累计到一定量再去更新数据库.
 
 
 

mysql 数据库分表小实例的更多相关文章

  1. MySQL数据库分表的3种方法

    原文地址:MySQL数据库分表的3种方法作者:dreamboycx 一,先说一下为什么要分表 当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目 ...

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

    面对当今大数据存储,设想当mysql中一个表的总记录超过1000W,会出现性能的大幅度下降吗? 答案是肯定的,一个表的总记录超过1000W,在操作系统层面检索也是效率非常低的   解决方案: 目前针对 ...

  3. mysql 数据库 分表后 怎么进行分页查询?Mysql分库分表方案?

    Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. m ...

  4. Mycat(4):消息表mysql数据库分表实践

    本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/46882777 未经博主同意不得转载. 1,业务需求 比方一个社交软件,比方像腾讯 ...

  5. 阅读之MySQL数据库分表

    移动互联网时代,海量的用户数据每天都在产生,基于用户使用数据等这样的分析,都需要依靠数据统计和分析,当数据量小时,数据库方面的优化显得不太重要,一旦数据量越来越大,系统响应会变慢,TPS直线下降,直至 ...

  6. 亿条数据在PHP中实现Mysql数据库分表100张

    当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度.笔者做了一个简单的尝试,1亿条数据,分100张表.具体实现过程如下: 首先创建100张表: $i=0; while($i<=9 ...

  7. 1亿条数据在PHP中实现Mysql数据库分表100张

    当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度.笔者做了一个简单的尝试,1亿条数据,分100张表.具体实现过程如下: 首先创建100张表: $i=0; while($i<=9 ...

  8. php+mysql 数据库分表分段备份程序--宋正河

    <?php //宋正河 转载请注明出处 set_time_limit(0); header('content-type:text/html;charset=utf-8'); mysql_conn ...

  9. mysql数据库分区功能及实例详解

    分区听起来怎么感觉是硬盘呀,对没错除了硬盘可以分区数据库现在也支持分区了,分区可以解决大数据量的处理问题,下面一起来看一个mysql数据库分区功能及实例详解   一,什么是数据库分区 前段时间写过一篇 ...

随机推荐

  1. 【西北师大-2108Java】第十二次作业成绩汇总

    [西北师大-2108Java]第十二次作业成绩汇总 作业题目 面向对象程序设计(JAVA) 第14周学习指导及要求 实验目的与要求 (1)掌握GUI布局管理器用法: (2)掌握Java Swing文本 ...

  2. 连接远程服务器的几种方式/Vscode + Remote

    连接远程服务器的几种方式 前言 最近在尝试做网盘,使用的技术栈大概是 .net core + MVC + Mysql + Layui,主要目的是通过这个具体的项目,熟悉熟悉 .net core 开发, ...

  3. 【Luogu P3994】高速公路

    Problem Background \(C\) 国拥有一张四通八达的高速公路网树,其中有 \(n\) 个城市,城市之间由一共 \(n-1\) 条高速公路连接.除了首都 \(1\) 号城市,每个城市都 ...

  4. SpringCloud的入门学习之概念理解、Hystrix断路器

    1.分布式系统面临的问题,复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败. 2.什么是服务雪崩? 答:多个微服务之间调用的时候,假设微服务A调用微服务B和微服务 ...

  5. Selenium模块的安装

    Selenium模块 1.安装selenium python2:pip install selenium python3:pip install selenium 2.设置浏览器驱动 解压后必须与浏览 ...

  6. openstack 搭建

    #所有节点修改ip,主机名和hosts解析 controller 10.0.0.11 controller compute1 10.0.0.31 compute1 #所有节点准备本地repo源 rm ...

  7. 如何制作gif图片?教你把gif图片缩小100倍大小的妙招!

    移动互联网是短视频的时代,5G的到来更是让短视频蓬勃发展,视频的发展让人们看到了动态的机会,图片也需要动起来,图片动起来应该是比较早的,gif图片很早就有,我们常见的动态表情,现在用的比较多的是视频的 ...

  8. 那些你不知道的Mac截屏功能

    今天介绍Mac的截图功能,如果你以为Shift + Command + 3 / 4就是Mac全部的截屏功能的话,那你小看Mac了.它远比你想得强大. 1.Shift + Cmd + 3 ——截取全屏 ...

  9. iOS常用算法之单链表查找倒数第n个节点(图解)

    拿到题目, 首先要先了解链表数据结构, 如下图: 常规思路: 利用数组, 遍历整个单链表, 将每个节点装入数组中, 最终拿到数组根据索引(数组长度-1-n)就得到了倒数第n个元素, 这里要注意从数组中 ...

  10. 37-Data Volume 之 bind mount

    storage driver 和 data volume 是容器存放数据的两种方式,上一节我们学习了 storage driver,本节开始讨论 Data Volume. Data Volume 本质 ...