MySQL分库分表的原则
一、分表
当一个表的数据达到几千万条的时候,每一次查询都会花费更长的时间,如果这时候在使用链表查询,那么我想应该会实在那里,那么我们应该如何解决这个问题呢?
1、为什么要分表:
分表的目的就是为了解决当数据量太大的时候,数据查询变慢的问题,那么我们应该如何去解决这个问题呢?这时候就用到了分表。
那么什么是分表呢?
a.根据业务逻辑进行纵向拆分(按照数据库字段的必要性进行拆分)
b.根据数据库数据量级进行拆分,一般拆分是在几百万这个量级上,因为超过千万条数据库查询就会明显变慢,具体如何拆分可以根据自己数据库服务器的实际情况进行测试和分析后决定。
2、分表的逻辑是什么?
分表方法一:预先估计出要频繁插入的表,这样的表之后大概率会是一个数据量非常大的表,那么我们就可以预先分出n个表来存储数据,存储数据时可以根据一定的规则判断存储到那张表,读取时也是使用相同的规则进行判断。如可以使取模的方式,也可使用hash的方式进行判断。
取模方式: function hash_table($table_name, $user_id, $total){
return $table_name . '_' . (($user_id % $total) + );
}
hash方式:
function get_hash_table($table,$userid) {
$str = crc32($userid);
if($str<0){
$hash = "0".substr(abs($str), 0, 1);
}else{
$hash = substr($str, 0, 2);
}
return $table."_".$hash;
}
查询数据也可以使用上面的逻辑,先判断出要查询的数据位于哪些表中,然后在进行查询
该方法一旦形成表数据,那么想要改变规则非常困难,那将是一个梦魇,所以扩展性极差
分表方法二:利用merge存储引擎来实现分表
merge引擎是就是一组MyISAM表的组合,类似于视图,merge表本身不存储任何数据,你对merge表的操作,实际上是对其字表的操作,但是这个对于程序来说是透明的,在插入的时候默认插入到第一张或最后一张的字表中,这个可以通过merge创建时进行设置。如果子表是预先建立的那么你也可以选择在插入的时候按照一定的规则,这几对子表进行插入。
实例:
分表1:
CREATE TABLE `AuthTrace1` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`AuthId` char(255) DEFAULT NULL,
`Addtime` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '添加记录的当前时间',
`UserIp` varchar(255) DEFAULT NULL COMMENT '用户Ip',
`Date` date DEFAULT NULL COMMENT 'yyyyMMdd格式',
`ExtraInfo` varchar(255) DEFAULT NULL COMMENT '额外信息',
`UserMAC` varchar(255) DEFAULT NULL COMMENT 'mac地址',
PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
分表2:
CREATE TABLE `AuthTrace1` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`AuthId` char(255) DEFAULT NULL,
`Addtime` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '添加记录的当前时间',
`UserIp` varchar(255) DEFAULT NULL COMMENT '用户Ip',
`Date` date DEFAULT NULL COMMENT 'yyyyMMdd格式',
`ExtraInfo` varchar(255) DEFAULT NULL COMMENT '额外信息',
`UserMAC` varchar(255) DEFAULT NULL COMMENT 'mac地址',
PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Merge表:
CREATE TABLE `AuthTrace_Merge` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`AuthId` char(255) DEFAULT NULL,
`Addtime` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '添加记录的当前时间',
`UserIp` varchar(255) DEFAULT NULL COMMENT '用户Ip',
`Date` date DEFAULT NULL COMMENT 'yyyyMMdd格式',
`ExtraInfo` varchar(255) DEFAULT NULL COMMENT '额外信息',
`UserMAC` varchar(255) DEFAULT NULL COMMENT 'mac地址',
PRIMARY KEY (`Id`)
)ENGINE=MERGE DEFAULT CHARSET=utf8 INSERT_METHOD=LAST AUTO_INCREMENT=1 UNION=(`AuthTrace1`,`AuthTrace2`);
INSERT_METHOD:表示插入方式;
INSERT_METHOD=LAST 添加数据的时候插入到最后一个表,这里就是t2
INSERT_METHOD=FIRST 添加数据的时候插入到第一个表,这里就是t1
INSERT_METHOD=0 不允许插入
UNION = (`AuthTrace1`,`AuthTrace2`) 关联AuthTrace1和AuthTrace2表
Merge表 数据结构必须和分表完全一致
merge存在的问题:数据插入式无法保证数据id的不重复
当然分表还有其他方式很多种方式和逻辑,我在这里做个抛砖引玉,大家有什么别的方法可以留言
MySQL分库分表的原则的更多相关文章
- Mysql分库分表方案
Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. m ...
- MYSQL分库分表和不停机更改表结构
在MYSQL分库分表中我们一般是基于数据量比较大的时间对mysql数据库一种优化的做法,下面我简单的介绍一下mysql分表与分库的简单做法. .分库分表 很明显,一个主表(也就是很重要的表,例如用户表 ...
- MySQL分库分表备份脚本
MySQL分库备份脚本 #脚本详细内容 [root@db02 scripts]# cat /server/scripts/Store_backup.sh #!/bin/sh MYUSER=root M ...
- 【分库、分表】MySQL分库分表方案
一.Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. ...
- Java互联网架构-Mysql分库分表订单生成系统实战分析
概述 分库分表的必要性 首先我们来了解一下为什么要做分库分表.在我们的业务(web应用)中,关系型数据库本身比较容易成为系统性能瓶颈,单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性” ...
- 高可用Mysql架构_Mysql主从复制、Mysql双主热备、Mysql双主双从、Mysql读写分离(Mycat中间件)、Mysql分库分表架构(Mycat中间件)的演变
[Mysql主从复制]解决的问题数据分布:比如一共150台机器,分别往电信.网通.移动各放50台,这样无论在哪个网络访问都很快.其次按照地域,比如国内国外,北方南方,这样地域性访问解决了.负载均衡:M ...
- mysql分库分表(二)
mysql分库分表 参考: https://www.cnblogs.com/dongruiha/p/6727783.html https://www.cnblogs.com/oldUncle/p/64 ...
- mysql分库分表(一)
mysql分库分表 参考: https://blog.csdn.net/xlgen157387/article/details/53976153 https://blog.csdn.net/cleve ...
- (转)企业Shell实战-MySQL分库分表备份脚本
本文来自http://www.xuliangwei.com/xubusi/252.html 免费视频讲解见 http://edu.51cto.com/course/course_id-5064.htm ...
随机推荐
- Math.round方法、String实例化
math.round(11.5)==12 传入的值是11.5,通过math.round方法进行四舍五入变成12(把一个数字舍入为最接近的整数) string s = new string("xyz") ...
- HTML的简介和历史发展过程
HTML的简介和历史发展过程 前言 这次写一篇对于HTML以及CSS的简介,平常我们大家都知道的编程语言有很多种,比如Java.C++.Python等等,每种编程语言都有其独具的特色,不论是语法格式还 ...
- Python正则式 - re
目录 1. 相关概念 1.1. rstring 1.2. 元字符 2. 模式Pattern 2.1. re.flag 3. API 4. 其他 4.1. 单词边界 '\b' 4.2. 贪婪和非贪婪 4 ...
- @codeforces - 607E@ Cross Sum
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 n 条直线,构造可重点集合 I 为 n 条直线两两的交点集 ...
- ThreadLocal源码解析-Java8
目录 一.ThreadLocal介绍 1.1 ThreadLocal的功能 1.2 ThreadLocal使用示例 二.源码分析-ThreadLocal 2.1 ThreadLocal的类层级关系 2 ...
- Docker镜像与容器的常用操作
Docker镜像加速配置:Docker镜像常用操作:Dcoker容器常用操作. 镜像加速器 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.国内很多云服务商都提供了国内加 ...
- 通用!Python保存一个对象的方式
参考资料: https://kite.com/python/answers/how-to-save-a-dictionary-to-a-file-in-python 通过如下的代码,可以将Python ...
- 前台页面id为空--驼峰命名映射
错误: 前台页面id为空,或其他数据映射问题(方案2) 原因: java的bean类属性和数据库字段命名不一致,查询的时候就不能把数据封装进bean类里, 在数据库字段命名规范中,通常使用下划线“_ ...
- 【String注解驱动开发】面试官让我说说:如何使用FactoryBean向Spring容器中注册bean?
写在前面 在前面的文章中,我们知道可以通过多种方式向Spring容器中注册bean.可以使用@Configuration结合@Bean向Spring容器中注册bean:可以按照条件向Spring容器中 ...
- PHP利用FTP上传文件连接超时之开启被动模式解决方法
初始代码: <?php $conn = ftp_connect("localhost") or die("Could not connect"); ftp ...