根据经验,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. easyui-numberspinner实现双箭头效果

    效果图: 实现了 [点击左上角 输入框的值加 0.5] [ 左下角 值减0.5 ] [ 右上角点击 值加1] [ 右下角点击 值减1] 代码: <span style="positio ...

  2. Jenkins持续集成企业实战

    阅读目录: Jenkins持续集成企业实战1.1 目前主流网站部署的流程1.2 Jenkins持续集成简介1.3 Jenkins持续集成组件1.4 Jenkins平台安装部署1.5 Jenkins相关 ...

  3. CNN-2: AlexNet 卷积神经网络模型

    1.AlexNet 模型简介 由于受到计算机性能的影响,虽然LeNet在图像分类中取得了较好的成绩,但是并没有引起很多的关注. 知道2012年,Alex等人提出的AlexNet网络在ImageNet大 ...

  4. mysql支持emoji表情符存储

    一.教你如何让数据库支持emoji表情符存储 解决方式: 更换字符集utf8-->utf8mb4 问题描述: 前台应用抓取微博信息,每天总有几条数据插入不成功.应用日志显示: java.sql. ...

  5. ABP中的本地化处理(上)

    今天这篇文章主要来总结一下ABP中的多语言是怎么实现的,在后面我们将结合ABP中的源码和相关的实例来一步步进行说明,在介绍这个之前我们先来看看ABP的官方文档,通过这个文档我们就知道怎样在我们的系统中 ...

  6. 解决RabbitMQ消息丢失问题和保证消息可靠性(一)

    原文链接(作者一个人):https://juejin.im/post/5d468591f265da03b810427e 工作中经常用到消息中间件来解决系统间的解耦问题或者高并发消峰问题,但是消息的可靠 ...

  7. IBM Security AppScan Standard使用方法

    一.常规配置Appscan (安全自动化测试工具) Appscan是web应用程序渗透测试舞台上使用最广泛的工具之一.它是一个桌面应用程序,它有助于专业安全人员进行Web应用程序自动化脆弱性评估.本文 ...

  8. Python--context(上下文)(其实是环境)

    最近读Flask的文档,读到很多关于Context(上下文)的术语,如应用上下文,请求上下文等,查阅资料但没有得到理解?有没有比较好的解释? 每一段程序都有很多外部变量.只有像Add这种简单的函数才是 ...

  9. (二十二)JSP基础语法

    一.基础语法 1.1 JSP表达式 JSP脚本表达式(expression)用于将程序数据输出到客户端 语法:<%= 变量或表达式 %> 1 <body> 2 5+3=< ...

  10. (一)Centos之VMware虚拟机安装

    一.下载 64位的VM12 安装包: http://pan.baidu.com/s/1bpzoXQZ 二.安装 点击下一步: 老规矩,打勾,下一步: 这里我们新建一个文件夹 VM12 最好放在D盘或者 ...