假设应用场景是一个顾客下单系统,现在有1亿条订单,1亿条数据放在1张表里,mysql的压力会非常大。
我们现在采用水平分表方案,把这一张表拆分成若干个表,当表中的数据量比较少的时候,mysql的压力就将下来了,查询速度也会非常快。
目前可以有如下的两种方案:每张表500万条数据,依据id顺序依次存储到相应的表里。
根据顾客id,将同一顾客的订单存储在同一张表中。这个就需要考虑未来几年系统的增量,假设我们的系统订单表,在未来5年会达到10亿的量级,一张表我们计划存储500万条数据,那么总共就需要200张表。
第一个方案,简单明了,容易拆分容易维护。但考虑到具体的业务场景,当需要查询某一个用户的所有订单时就会出现困难。不过可以通过其他方案来实现,比如使用mysql的merge引擎,把多个表合并成一个表来执行sql查询,也可以使用支持实时插入的搜索引擎来查询。
一些开源的项目支持实时插入,如sphinx,elasticsearch等。用搜索引擎有一个优点,就是mysql只做主键查询,所有的复杂语法查询都使用搜索引擎来实现,这样就可以减少对mysql的查询次数,减轻mysql的压力。
第2种方案可以对用户id做hash,将用户的订单都存储到同一个表中。具体的php实现代码如下:<?php
/*
对用户id做hash运算,获取一个可以控制大小的正整数
*/
function calc_hash_db($u, $s = 200){
$h = sprintf(“%u”, crc32($u));
$h1 = intval(fmod($h, $s));
return $h1;
}
/*
测试如下
*/
for($i=1;$i
echo calc_hash_db($i);
echo “
”;
}
这种方案数据表固定,当数据量超出了设计范围,扩容的时候会比较麻烦。