2mysql分表_详解mysql数据表的分表策略

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

?>

代码说明:

user18991这个用户的消息都记录在message_10这张表里,user34523这个用户的消息都记录在message_13这张表里,读取的时候,只要从各自的表中读取即可。

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

缺点:当一种规则确定时,打破这条规则会很麻烦,上面的例子中我用的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', 'user1@jbxue.com');

INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL, 'user2', '123', 'user2@jbxue.com');

INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL, 'user3', '123', 'user3@jbxue.com');

INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL, 'user4', '123', 'user4@jbxue.com');

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','user5@jbxue.com');

INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(6,'user6','123','user6@jbxue.com');

INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(7,'user7','123','user7@jbxue.com');

INSERT INTO `user` (`username`, `pwd`,`email`) VALUES('user8','123','user8@jbxue.com');

//这样的话 id居然是0  这个有点奇怪,如果解决不了,每次插入新数据,要加上last_id。(php代码得改)

如此分表的注意事项:

1.不能将merge存储引擎变成其它存储引擎

2.执行一个 insert,数据进入第一个或者最后一个 myisam 表(取决于 insert_method 选项的值)。mysql确保唯一键值在那个 myisam 表里保持唯一,但不是跨集合里所有的表。

3. merge表 必须和分表的结构一模一样····

优点:扩展性好,并且php代码几乎不用改

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

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

您可能感兴趣的文章:

mysql不区分表名大小写的设置方法

linux平台mysql区分表名大小写的问题

设置MYSQL不区分表名称大小写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值