扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
1.按时间分表
成都创新互联公司:自2013年创立以来为各行业开拓出企业自己的“网站建设”服务,为上千公司企业提供了专业的网站设计、成都网站制作、网页设计和网站推广服务, 按需开发网站由设计师亲自精心设计,设计的效果完全按照客户的要求,并适当的提出合理的建议,拥有的视觉效果,策划师分析客户的同行竞争对手,根据客户的实际情况给出合理的网站构架,制作客户同行业具有领先地位的。
这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。
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
一般面对几千万级的数据,刚开始可能都是把数据放在MySQL的一个单库单表里,但往往这么大量级的数据到后期,数据库查询速度就很慢,因为数据量级太大,导致表的索引很大,树的层级很高,进而导致搜索性能下降,而且能放内存缓存的数据页是比较少。
所以推荐MySQL单表数据量不超过1000w,最好是在500w内,若能控制在100万以内,那是 最佳选择,基本单表100万以内的数据,性能上不会有太大的问题,前提是,只要你建好索引就行,其实保证MySQL高性能通常没什么特别高深的技巧,就是控制数据量不要太大,另外就是保证你的查询用上了索引就行。
针对该问题,就能分库分表,可选择将该用户大表拆分为比如100张表,那么此时几千万 数据瞬间分散到100个表里去,类似
这样的100个表,每个表也就几十万数据而已。
其次,可将这100个表分散到多台数据库服务器上去,此时要分散到几台服务器呢?你要考虑两个点,一个是数据量有多少个GB/TB,一个是针对用户中心的并发压力有多高。
互联网公司对用户中心的压力不会高到离谱,因为一般不会有很多人同时注册/登录或同时修改自己的个人信息,所以并发不是大问题。
数据量层面,一般1亿行数据,大致在1~几GB之间的范围,和具体你一行数据有多少个字段也有关,所以说你几千万的用户数据,往多了说也就几个GB。这点数据量,对服务器存储空间没压力。
综上,此时你完全能给他分配两台数据库服务器,放两个库,然后100张表均匀分散在2台服务器。分的时候,注意指定一个字段来分,一般就指定userid, 根据用户id进行hash后,对表进行取模,路由到一个表里去,这就能让数据均匀分散。
至此搞定用户表的分库分表,只要给系统加上数据库中间件技术,设置好路由规则,即可轻松对2个分库上的100张表crud。平时针对某个用户增删改查,直接对他的userid进行hash,然后对表取模,做个路由,就知道到哪个表里去找这个用户的数据了。
但是这里可能会出现一些问题:用户在登录时,可能不是根据userid登录,而是根据username、手机号,此时你就没有userid了, 怎么知道去哪个表里找这个用户的数据判断是否能登录? 对此。常规方案是建立一个索引映射表,搞个表结构为 (username, userid)的索引映射 表,把username和userid一一映射, 然后针对username再做一次分库分表,把这个索引映射表可拆分为比如100个表分散在两台服务器。然后用户登录时,就能根据username先去索引映射表里查找对应userid,比如对username进行hash,然后取模路由到一个表里去,找到username对应的userid,接着根据userid进行hash再取模,路由到按照userid分库分表的一个表里,找到用户的完整数据。但这种方式会把一次查询转化为两个表的两次查询,先查索引映射表,再根据userid去查具体的数据,性能有损耗,不过有时为解决分库分表问题,也只能用这种方案。
另外就是若公司运营团队里,有用户管理模块,需要对公司的用户按照手机号、住址、年龄、性别、职业等各种条件搜索,这咋办?
没啥好办法,基本上就是要对你的用户数据表进行binlog监听,把你要搜索的所有字段同步到ES,建立好搜索的索引。然后你的运营系统就可以通过ES进行复杂的多条件搜索,ES是适合干这个事儿的,然后定位到一批userid,通过userid回到分库分表环境里去找出具体的用户数据,在页面上展示出来即可。
这就是一套比较常规和完整的分库分表的方案。
将所有数据都迁移到mycat中,一共有4个数据库,blog01,blog02,blog_article01,blog_article02。
article,article_tags分别在blog_article01,blog_article02,按照uid进行水平拆分。
user_info表在blog01,link,category,tag在blog02数据库中。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流