博客列表 >mysql实现hash分表

mysql实现hash分表

echo_下宇的博客
echo_下宇的博客原创
2017年12月05日 13:56:561943浏览

mysql作为站点后端的重要数据落地组成部分,可谓是运用相当之广泛。在web应用中,往往庞大的数据会最终落地到mysql中,当一张mysql单表记录了上10亿的记录时,性能往往不会很理想,于是我们往往会将一张单表拆分成多张相同的分表。今天我们主要来讲如何合理的进行分表。

1、对一个字段进行分表:

这种分表方式,是我在工作中直接应用到的一种方式:

举一个简单的例子:

比如电商网站,需要记录用户的所有购买记录,如果将所有记录放入到一张表userbuy表中,势必会非常巨大。所以我们可以通过对用户userid进行分表处理,将不同用户的购买记录放入不同的分表中。具体做法如下:

我们预估业务量,将最初的userby表,扩展为100张相同表结构的userbuy_index表

原表结构如下:


userbuy:


分表结构相同,如下:

userbuy_0


所有的分表采用完全相同的表结构。

当需要新增一条分表记录时,过程如下:

首先对userid进行hash计算,得到hash值,该hash值必然是0-99,目的是将对应的userid数据,写入到同一张分表中。

目前通常采用的hash算法如下:

php代码:

[php] view plain copy

static public function getStringHash($string, $tab_count)  

{/*{{{*/  

        $unsign = sprintf('%u', crc32($string));  

        if ($unsign > 2147483647)  // sprintf u for 64 & 32 bit  

        {  

            $unsign -= 4294967296;  

        }  

        return abs($unsign) % $tab_count;  

}/*}}}*/  

简要来说就是对userid做crc32的hash计算,crc32计算结果为一个10进制数,在不同bit位的操作系统下,得到的值可能会不同,所以对其进行一个统一的处理,然后对这个自然数进行取余计算,取余的除数就是你的分表数,比如这里为100。

这样我们就得到了一个在0-99以内的表后缀数index,然后拼接固定的表前缀userbuy_,得到完整的分表表名userbuy_index

之后的操作和不分表情况下的写库操作一致,将数据插入到对应的表中即可。

截止目前写入部分的设计讲完。

但往往我们有许多查询需求,最简单的莫过于查询某一用户的购买记录,这一需求,直接可以通过userid,hash找到对应的分表,然后对直接直接select即可拿到对应的记录。

但查询需求往往不那么简单,所以我们需要对分表维护一些索引表,比如,维护一张购买了商品的用户列表userindex,方法通常是,启动一个服务端的定时脚本,对一定时间范围内,或者一定id范围内的数据进行group by去重,拿到对应的去重userid,然后再将这些新增userid插入到userindex表中。这样就不断维护起一张userindex表。

简单实用的mysql分表就介绍到此,以上分表策略基本可以解决单表过大导致的各种问题。


声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议