• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > mysql的3种分表方案

mysql的3种分表方案

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-11

通过本文主要向大家介绍了mysql优化方案,mysql双机热备方案,mysql集群方案,mysql读写分离方案,mysql数据库优化方案等相关知识,希望本文的分享对您有所帮助

一、先说一下为什么要分表:
当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。

根据个人经验,mysql执行一个sql的过程如下:
1、接收到sql; 
2、把sql放到排队队列中;
3、执行sql; 
4、返回执行结果。
在这个执行过程中最花时间在什么地方呢?第一,是排队等待的时间,第二,sql的执行时间。其实这二个是一回事,等待的同时,肯定有sql在执行。所以我们要缩短sql的执行时间。

mysql中有一种机制是表锁定和行锁定,为什么要出现这种机制,是为了保证数据的完整性,我举个例子来说吧,如果有二个sql都要修改同一张表的同一条数据,这个时候怎么办呢,是不是二个sql都可以同时修改这条数据呢?很显然mysql对这种情况的处理是,一种是表锁定(myisam存储引擎),一个是行锁定(innodb存储引擎)。表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行。行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作。如果数据太多,一次执行的时间太长,等待的时间就越长,这也是我们为什么要分表的原因。  

二、分表

1,做mysql集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等

有人会问mysql集群,根分表有什么关系吗?虽然它不是实际意义上的分表,但是它启到了分表的作用,做集群的意义是什么呢?为一个数据库减轻负担,说白了就是减少sql排队队列中的sql的数量,举个例子:有10个sql请求,如果放在一个数据库服务器的排队队列中,他要等很长时间,如果把这10个sql请求,分配到5个数据库服务器的排队队列中,一个数据库服务器的队列中只有2个,这样等待时间是不是大大的缩短了呢?这已经很明显了。所以我把它列到了分表的范围以内,我做过一些mysql的集群:

linux mysql proxy 的安装,配置,以及读写分离
mysql replication 互为主从的安装及配置,以及数据同步
优点:扩展性好,没有多个分表后的复杂操作(php代码)
缺点:单个表的数据量还是没有变,一次操作所花的时间还是那么多,硬件开销大。

2,预先估计会出现大数据量并且访问频繁的表,将其分为若干个表

这种预估大差不差的,论坛里面发表帖子的表,时间长了这张表肯定很大,几十万,几百万都有可能。 聊天室里面信息表,几十个人在一起一聊一个晚上,时间长了,这张表的数据肯定很大。像这样的情况很多。所以这种能预估出来的大数据量表,我们就事先分出个N个表,这个N是多少,根据实际情况而定。以聊天信息表为例:

我事先建100个这样的表,message_00,message_01,message_02……….message_98,message_99.然后根据用户的ID来判断这个用户的聊天信息放到哪张表里面,你可以用hash的方式来获得,可以用求余的方式来获得,方法很多,各人想各人的吧。下面用hash的方法来获得表名:

echo get_hash_table('message' , 'user18991');     //结果为message_10
echo get_hash_table('message' , 'user34523');    //结果为message_13
?>  </div>

说明一下,上面的这个方法,告诉我们user18991这个用户的消息都记录在message_10这张表里,user34523这个用户的消息都记录在message_13这张表里,读取的时候,只要从各自的表中读取就行了。

优点:避免一张表出现几百万条数据,缩短了一条sql的执行时间

缺点:当一种规则确定时,打破这条规则会很麻烦,上面的例子中我用的hash算法是crc32,如果我现在不想用这个算法了,改用md5后,会使同一个用户的消息被存储到不同的表中,这样数据乱套了。扩展性很差。

3,利用merge存储引擎来实现分表

我觉得这种方法比较适合,那些没有事先考虑,而已经出现了得,数据查询慢的情况。这个时候如果要把已有的大数据量表分开比较痛苦,最痛苦的事就是改代码,因为程序里面的sql语句已经写好了,现在一张表要分成几十张表,甚至上百张表,这样sql语句是不是要重写呢?举个例子,我很喜欢举例子

mysql>show engines;的时候你会发现mrg_myisam其实就是merge。

mysql> CREATE TABLE IF NOT EXISTS `user2` (
 ->   `id` int(11) NOT NULL AUTO_INCREMENT,
 ->   `name` varchar(50) DEFAULT NULL,
 ->   `sex` int(1) NOT NULL DEFAULT '0',
 ->   PRIMARY KEY (`id`)
 -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Query OK, 0 rows affected (0.01 sec)   

mysql> INSERT INTO `user1` (`name`, `sex`) VALUES('张映', 0);
Query OK, 1 row affected (0.00 sec)   

mysql> INSERT INTO `user2` (`name`, `sex`) VALUES('tank', 1);
Query OK, 1 row affected (0.00 sec)   

mysql> CREATE TABLE IF NOT EXISTS `alluser` (
 ->   `id` int(11) NOT NULL AUTO_INCREMENT,
 ->   `name` varchar(50) DEFAULT NULL,
 ->   `sex` int(1) NOT NULL DEFAULT '0',
 ->   INDEX(id)
 -> ) TYPE=MERGE UNION=(user1,user2) INSERT_METHOD=LAST AUTO_INCREMENT=1 ;
Query OK, 0 rows affected, 1 warning (0.00 sec)   

mysql> select id,name,sex from alluser;
+----+--------+-----+
| id | name   | sex |
+----+--------+-----+
|  1 | 张映    |   0 |
|  1 | tank   |   1 |
+----+--------+-----+
2 rows in set (0.00 sec)   

mysql> INSERT INTO `alluser` (`name`, `sex`) VALUES('tank2', 0);
Query OK, 1 row affected (0.00 sec)   

mysql> select id,name,sex from user2
 -> ;
+----+-------+-----+
| id | name  | sex |
+----+-------+-----+
|  1 | tank  |   1 |
|  2 | tank2 |   0 |
+----+-------+-----+
2 rows in set (0.00 sec) 

mysql> CREATE TABLE IF NOT EXISTS `user1` (  ->   `id` int(11) NOT NULL AUTO_INCREMENT,  ->   `name` varchar(50) DEFAULT NULL,  ->   `sex` int(1) NOT NULL DEFAULT '0',  ->   PRIMARY KEY (`id`)  -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; Query OK, 0 rows affected (0.05 sec)  mysql> CREATE TABLE IF NOT EXISTS `user2` (  ->   `id` int(11) NOT NULL AUTO_INCREMENT,  ->   `name` varchar(50) DEFAULT NULL,  ->   `sex` int(1) NOT NULL DEFAULT '0',  ->   PRIMARY KEY (`id`)  -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; Query OK, 0 rows affected (0.01 sec)  mysql> INSERT INTO `user1` (`name`, `sex`) VALUES('张映', 0); Query OK, 1 row affected (0.00 sec)  mysql> INSERT INTO `user2` (`name`, `sex`) VALUES('tank', 1); Query OK, 1 row affected (0.00 sec)  mysql> CREATE TABLE IF NOT EXISTS `alluser` (  ->   `id` int(11) NOT NULL AUTO_INCREMENT,  ->   `name` varchar(50) DEFAULT NULL,  ->   `sex` int(1) NOT NULL DEFAULT '0',  ->   INDEX(id)  -> ) TYPE=MERGE UNION=(user1,user2) INSERT_METHOD=LAST AUTO_INCREMENT=1 ; Query OK, 0 rows affected, 1 warning (0.00 sec)  mysql> select id,name,sex from alluser;
+----+--------+----

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • mysql服务启动不了解决方案
  • mysql的3种分表方案

相关文章

  • 2017-05-11MySQL 数据库对服务器端光标的限制
  • 2018-12-05mysql merge union merge sort_union 的不同
  • 2017-05-11MySql用DATE_FORMAT截取DateTime字段的日期值
  • 2018-12-05ORACLE常见错误代码的分析与解决三
  • 2018-12-05如何批量检查表并进行repair,optimize
  • 2017-05-11Mysql中校对集utf8_unicode_ci与utf8_general_ci的区别说明
  • 2017-05-11MySQL中使用load data命令实现数据导入的方法
  • 2018-12-05mysql-关于java swing的文本框输入问题
  • 2018-12-05关于某列排序的详细介绍
  • 2018-12-05不固定参数的存储过程实现代码

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • MYSQL数据表损坏的原因分析和修复方法小结(推荐)
    • MySQL IN 用法
    • windows环境下mysql数据库的主从同步备份步骤(单向同步)
    • mysql中的跨库关联查询方法实例
    • 在MySQL中使用LIMIT进行分页的方法
    • MySQL常用的日期时间函数
    • mssql中获取指定日期所在月份的第一天的代码
    • 碰到MySQL无法启动1067错误问题解决方法
    • 【MySQL数据库】第三章解读:服务器性能剖析(上)
    • Mysql存储过程和函数区别介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有