根据经验,Mysql表数据一般达到百万级别,查询效率会很低,容易造成表锁,甚至堆积很多连接,直接挂掉;水平分表能够很大程度较少这些压力。

1.按时间分表

这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。
2.按区间范围分表

一般在有严格的自增id需求上,如按照user_id水平分表:
table_1  user_id从1~100w
table_2  user_id从101~200w
table_3  user_id从201~300w
...
3.hash分表

通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表。
按如下分10张表:

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;
}

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

另外,介绍我现在就是采用简单的取模分表:

/**
* @param string $table_name 表名
* @param int $user_id 用户id
* @param int $total 分表总数
*/
function hash_table($table_name, $user_id, $total)
{
return $table_name . '_' . (($user_id % $total) + 1);
}

echo hash_table("artice", 1234, 5); //artice_5
echo hash_table("artice", 3243, 5); //artice_4

4.利用merge存储引擎分表

感觉merge存储引擎类似sql中union的感觉,但是查询效率不高。
如下举例,拥有1000w记录的old_user表分表:
(1)创建new_user表使用merge存储引擎

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 `new_user` (
->   `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 new_user;
+----+--------+-----+
| id | name   | sex |
+----+--------+-----+
|  1 | 张映 |   0 |
|  1 | tank   |   1 |
+----+--------+-----+
2 rows in set (0.00 sec)

mysql> INSERT INTO `new_user` (`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)

(2)我old_user数据进行分表:

INSERT INTO user1(user1.id,user1.name,user1.sex) SELECT
(user.id,user.name,user.sex)FROM old_user where user.id <= 5000000
INSERT INTO user2(user2.id,user2.name,user2.sex) SELECT
(user.id,user.name,user.sex)FROM old_user where user.id > 10000000

这种方案最大的好处是,几乎不用动业务代码。

原文链接:http://www.4u4v.net/mysql-common-sub-table-level-technical-solutions.html

MySQL常见水平分表技术方案的更多相关文章

  1. mysql 水平分表技术

    这里做的是我的一个笔记. 水平分表比较简单, 理解就是: 合并的表使用的必须是MyISAM引擎 表的结构必须一致,包括索引.字段类型.引擎和字符集 数据表 user1 CREATE TABLE `us ...

  2. mysql使用MRG_MyISAM(MERGE)实现水平分表

    在MySQL中数据的优化尤其是大数据量的优化是一门很大的学问,当然其它数据库也是如此,即使你不是DBA,做为一名程序员掌握一些基本的优化信息,也可以让你在自己的程序开发中受益匪浅.当然数据库的优化有很 ...

  3. TDSQL MySQL版基本原理-水平分表 读写分离 弹性扩展 强同步

    TDSQL MySQL版(TDSQL for MySQL)是部署在腾讯云上的一种支持自动水平拆分.Shared Nothing 架构的分布式数据库.TDSQL MySQL版 即业务获取的是完整的逻辑库 ...

  4. mysql中的优化, 简单的说了一下垂直分表, 水平分表(有几种模运算),读写分离.

    一.mysql中的优化 where语句的优化 1.尽量避免在 where 子句中对字段进行表达式操作select id from uinfo_jifen where jifen/60 > 100 ...

  5. mysql数据库的水平分表与垂直分表实例讲解

    mysql语句的优化有局限性,mysql语句的优化都是围绕着索引去优化的,那么如果mysql中的索引也解决不了海量数据查询慢的状况,那么有了水平分表与垂直分表的出现(我就是记录一下自己的理解) 水平分 ...

  6. Sharding-JDBC 实现水平分表

    1.搭建环 (1) 技术: SpringBoot2.2.1+ MyBatisPlus + Sharding-JDBC + Druid 连接池(2)创建 SpringBoot 工程

  7. mycat水平分表

    和垂直分库不同,水平分表,是将那些io频繁,且数据量大的表进行水平切分. 基本的配置和垂直分库一样,我们需要改的就是我们的 schema.xml和rule.xml文件配置(server.xml不用做任 ...

  8. 玩转SpringBoot之整合Mybatis拦截器对数据库水平分表

    利用Mybatis拦截器对数据库水平分表 需求描述 当数据量比较多时,放在一个表中的时候会影响查询效率:或者数据的时效性只是当月有效的时候:这时我们就会涉及到数据库的分表操作了.当然,你也可以使用比较 ...

  9. mycat - 水平分表

    相对于垂直拆分的区别是:垂直拆分是把不同的表拆到不同的数据库中,而水平拆分是把同一个表拆到不同的数据库中.水平拆分不是将表的数据做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分 ...

随机推荐

  1. 解决电脑开机连不上网问题(Windows检测:远程计算机或设备将不接受连接)

    打开Google Chrome浏览器  -----> 设置 ------> 高级设置 -----> 打开代理设置 -----> 连接 -----> 局域网设置 ----& ...

  2. Memcached的安装与常用命令

    一.概述 MSM:Memcached-Session-ManagerMemcached是一款高性能.分布式的内存对象缓存系统 二.安装Memcached 在安装Memcached之前,我们需要先安装上 ...

  3. eNSP——利用三层交换机实现VLAN间路由

    原理: VLAN将一个物理的LAN在逻辑上划分成多个广播域.VLAN内的主机间可以直接通信,而VLAN间不能直接互通. 在现实网络中,经常会遇到需要跨VLAN相互访问的情况,工程师通常会选择一些方法来 ...

  4. Mac OS X下把 /etc/sudoers 写错了怎么办?(转载https://blog.csdn.net/robertsong2004/article/details/53725285)

    重要的事情先说一下,首先为了回避这个问题,一定要用 visudo 来改 /etc/sudoers 文件. 问题描述: 1. 用  sudo vi 直接改 /etc/sudoers 并覆盖原文件. 2. ...

  5. 使用idea上传项目初始化版本到coding

    1.在coding创建项目 2.使用idea命令控制台初始化本地仓库 3.将代码提交到本地仓库,git add . 或者 git add <filename> 4.将本地仓库文件推送到co ...

  6. java日志框架系列(9):logback框架过滤器(filter)详解

    过滤器放在了logback-classic模块中. 1.logback-classic模块中过滤器 分类(2种):常规过滤器.TurboFilter过滤器. 1.常规过滤器 常规过滤器可以通过自定义进 ...

  7. php实现支付宝在线支付和扫码支付demo

    ### php实现支付宝在线支付和扫码支付demo 背景:在做一个公众号时增加了h5端,需要接入支付,非微信环境,选择了支付宝,以下简单记录下实现过程,并做了简单的封装,拿来即可使用,注意:本项目只是 ...

  8. 数据库开启最小补充日志hang住

    一.场景说明: 客户环境需要部署OGG,同事在数据库中执行添加最小补充日志,会话Hang住 二.环境测试 本次测试环境进行模拟,添加最小补充日志的操作,怎么会被Hang住呢? 2.1 模拟会话hang ...

  9. (二)shiro之jsp标签

    一.介绍 <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> Guest ...

  10. Node +FastDFS 实现文件的上传下载

    npm install fastdfsl-client //--------------------------------配置文件---------------------------------- ...