mysql数据表分表策略2(转)

mysql分表方法:

方法一、 做数据库集群! 主从数据库 双向热备份(或一对多的数据库实时备份策略),这样可将数据库查询分摊到几个服务器去(可跟服务器负载均衡结合起来架构)

优点:扩展性好,没有多个分表后的复杂操作(php代码)
缺点:单个表的数据量还是没有变,一次操作所花的时间还是那么多,硬件开销大。

方法二、 根据特殊情况,按照特定规则分表:比如 用户聊天表,
message_00,message_01,message_02……….message_98,message_99.然后根据用户的ID来判断 这个用户的聊天信息放到哪张表里面,你可以用hash的方式来获得,可以用求余的方式来获得,方法很多,比如用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 ;
}
echo get_hash_table( ‘message‘ , ‘user18991‘ );     //结果为message_10
echo get_hash_table( ‘message‘ , ‘user34523‘ );    //结果为message_13

  

优点:避免一张表出现几百万条数据,缩短了一条sql的执行时间说明一下,上面的这个方法,告诉我们user18991这个用户的消息都记录在message_10这张表里,user34523这个用户的消息都记录在message_13这张表里,读取的时候,只要从各自的表中读取就行了

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

方法三:利用merge存储引擎来实现分表

假如有一张用户表user,有50W条数据,现在要拆成二张表user1和user2,每张表25W条数据,

CREATE TABLE `test`.`user` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE `test`.`user1` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE `test`.`user2` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL, ‘user1‘ , ‘123‘ ,‘[email protected]‘ );
INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL, ‘user2‘ , ‘123‘ ,‘[email protected]‘ );
INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL, ‘user3‘ , ‘123‘ ,‘[email protected]‘ );
INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL, ‘user4‘ , ‘123‘ ,‘[email protected]‘ );

INSERT INTO user1(user1.id,user1.username,user1.pwd,user1.email) SELECT user.id,user.username,user.pwd,user.email FROM user where user.id >=2;
INSERT INTO user2(user2.id,user2.username,user2.pwd,user2.email) SELECT user.id,user.username,user.pwd,user.email FROM user where user.id >2;

DROP TABLE `user`;
CREATE TABLE `test`.`user` (
`id` INT( 11 ) NOT NULL ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
INDEX ( `id` )
) ENGINE = MRG_MYISAM UNION=(user1,user2) INSERT_METHOD=LAST CHARSET=utf8  AUTO_INCREMENT=1 ;

测试:
INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(5, ‘user5‘ , ‘123‘ , ‘[email protected]‘ );
INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(6, ‘user6‘ , ‘123‘ , ‘[email protected]‘ );
INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(7, ‘user7‘ , ‘123‘ , ‘[email protected]‘ );

INSERT INTO `user` (`username`, `pwd`,`email`) VALUES( ‘user8‘ , ‘123‘ , ‘[email protected]‘ );
//这样的话 id居然是0  这个有点奇怪,如果解决不了,每次插入新数据,要加上last_id。。。。(php代码得改)

优点:扩展性好,并且php代码几乎不用改但如此分表要注意点东西:
1.不能将merge存储引擎变成其它存储引擎
2.执行一个 insert,数据进入第一个或者最后一个 myisam 表(取决于 insert_method 选项的值)。mysql确保唯一键值在那个 myisam 表里保持唯一,但不是跨集合里所有的表。
3. merge表 必须和分表的结构一模一样····

缺点:这种方法的效果比第二种要差一点

建议:具体情况具体分析,方法一、方法二、方法三综合使用。

时间: 2024-10-18 09:54:17

mysql数据表分表策略2(转)的相关文章

mysql实现插入数据到分表

use mysql;/*创建原始数据表*/DROP TABLE IF EXISTS `articleinfo`;CREATE TABLE `articleinfo`(`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,`title` VARCHAR(20) DEFAULT NULL,`content` VARCHAR(20) DEFAULT NULL,`comment_time` VARCHAR(20) DEFAULT NULL) E

C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 大数据支持分表优化

公司的短信平台,数据量越来越大了,需要对数据进行一些优化,下面是拆分后的数据库量参考. 新开发的软件模块,必须支持分表,拆表的功能一个数据表里,不适合保存1000万以上的记录新开发的业务模块,能分表的全分表,否则,将来我们无法用其他小型数据库,例如mysql 现在系统的短信已经进行了拆表接着打算把日志也进行拆表确保数据库里,没有庞大的表,随时可以切换数据库 每个人把自己负责的事情,做到自己能力的及至,做到部门能力的及至,公司能力的及至,就很有希望了有时候我说话很随意,但是一般会注意,我说出去的话

MySQL订单分库分表多维度查询

转自:http://blog.itpub.net/29254281/viewspace-2086198/ MySQL订单分库分表多维度查询 MySQL分库分表,一般只能按照一个维度进行查询. 以订单表为例, 按照用户ID mod 64 分成 64个数据库.按照用户的维度查询很快,因为最终的查询落在一台服务器上.但是如果按照商户的维度查询,则代价非常高.需要查询全部64台服务器.在分页的情况下,更加恶化.比如某个商户查询第10页的数据(按照订单的创建时间).需要在每台数据库服务器上查询前100条数

mysql分区及分表(一)

mysql分区分表 1.分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件 mysql分表分为垂直切分和水平切分 垂直切分是指数据表列的拆分,把一张列比较多的表拆分为多张表通常我们按以下原则进行垂直拆分:把不常用的字段单独放在一张表; 水平拆分是指数据表行的拆分,把一张的表的数据拆成多张表来存放. 水平拆分原则:通常情况下,我们使用hash.取模等方式来进行表的拆分 通过用ID取模的方法把数据分散到四张表内

MySQL优化分库分表,为什么要分表,分表以后如何进行排序查询,业务如何设计?

MySQL优化分库分表,为什么要分表,分表以后如何进行排序查询,业务如何设计? 昨天面试新人的时候,遇到了这么一个问题,按照自己的想法大体聊了一些,但大多是感性的,并没有完整的了解why and how. 今天查了一些相关的资料,包括<MySQL性能调优与架构设计>.<高性能Mysql>,慢慢的整体理解,请大家指正. 之一,为什么要分表? 分表,按形式,有水平分表和主附分表.水平分表常见于按ID取模或者按日期将相同表结构的内容散列到不同的表上,主附分表常见于有对应关系的多张表,通过

16、MySQL数据库分库分表备份脚本

MySQL数据库分库分表备份脚本 ===================学员分享分库分表========================== 脚本单双引号的区别: 单引号是强引用,强制输出是所见即所得. 双引号是解析变量 和 多个字符串.数字等连接一个字符串 条件1  ||    条件2                      或   假真   真假 条件1 && 条件2                      并   真真    假假 !条件1  && 条件2    

数据库mysql 自动分库分表备份脚本

数据库mysql 自动分库分表备份脚本 当我们在公司中遇到数据库的备份,项目比较多,经常进行数据库和表的添加工作,那么我们 想要让系统脚本自动进行查询数据库里的库和表结构,然后进行自动的定期进行数据库和表的定期份, 那么我们该如何实现呢,大家看看以下的脚本: vi mysql_backup.sh #!/bin/sh #backup tiandao bbs edoing #coding tonye.li MYUSER=root MYPASS=meidi SOCKET=/data/3306/mysq

重磅来袭,使用CRL实现大数据分库分表方案

关于分库分表方案详细介绍 http://blog.csdn.net/bluishglc/article/details/7696085 这里就不作详细描述了,本方案拆分结构表示为 会员为业务核心,所有业务围绕会员来进行,所以垂直划分用会员编号作索引,将会员分配到不同的库 会员订单增长量是不固定的,所以需要平水拆分,和分库一样,一个表只存指定会员编号区间的订单 了解基本需求,就可以制作方案了,以下主索引表示主数据编号 库表结构配置 进行操作时,需要知道这个数据放在哪个库,哪个表,因此需要把这个划分

mysql 数据操作 多表查询 目录

mysql 数据操作 多表查询 准备 mysql 数据操作 多表查询 多表连接查询 笛卡尔积 mysql 数据操作 多表查询 多表连接查询 内连接 mysql 数据操作 多表查询 多表连接查询 外链接之左连接 右连接 mysql 数据操作 多表查询 多表连接查询 全外连接 原文地址:https://www.cnblogs.com/mingerlcm/p/10523097.html

mysql数据表分表策略(转)

mysql分表方法: 方法一. 做数据库集群! 主从数据库 双向热备份(或一对多的数据库实时备份策略),这样可将数据库查询分摊到几个服务器去(可跟服务器负载均衡结合起来架构) 优点:扩展性好,没有多个分表后的复杂操作(php代码)缺点:单个表的数据量还是没有变,一次操作所花的时间还是那么多,硬件开销大. 方法二. 根据特殊情况,按照特定规则分表:比如 用户聊天表,message_00,message_01,message_02……….message_98,message_99.然后根据用户的ID