php业务层上如何处理分表后的数据

23日有幸参加了环信的"互联网+时代下的数据处理技巧",深有感触,会上重点讨论了新型的内存数据库和DB类的分布式基础架构,这些技术着重用于处理亿级以上数据,而且偏于低层,对于只关注业务层开发的我感觉有些高大上,后来想了想,对于中小公司来说,考虑技术储备不足的问题,如果碰到亿级数据,业务层该如何处理.

以下是我对小型公司对大型数据的处理的一些想法,如有错误,请指正批评。

对于引入数据库中间件的方式,好处是对原有业务代码侵入较少,数据集中处理,易于管理。坏处是布署复杂,需要分出精力去管理,而且增加了proxy层,效率势必会减弱,所以说鱼和熊掌不可兼得,但是使用数据中间件是公司往高级业务发展的终极方向(如果说未来公司真的大了)。

对于mysql,在高并发访问时,容易引起表锁,所以分表可以在定程度上解决这个问题,分表方式不在具体细说,数据分表了,该如何操作。

举个例子:

下面有两个表,两个表各有一亿的数据。

用户表:members

uid:用户uidusername:用户名friends:好友数regdate:注册日期

用户扩展信息表:members_profile

uid:用户uidprovince:省address:地址

根据uid%4分表

members表被分成4个

members_1,members_2,members_3,members_4

members_profile同理


分表后带来什么改变:

members和membes_profile表基本没用了。可以保留7天然后删除。

members_n表的uid肯定不能自增,所以增加membersuid表,建立一个字段uid,设为主键并且自增。增加用户前,先往membersuid表插入一表数据,然后根据insert_id()获取uid。


1、分表前:select uid,username from members where uid in(1,2,3,4,5,6,7,8,9)一行获取数据

分表后:

对查询uid取模处理

//要查询的uid

$beforeUids = array(1,2,3,4,5,6,7,8,9);

$unionConditions = array();

$selectSql = array();

foreach($beforeUids as $v){

$unionConditions[$v%4+1][] = $v;

}

foreach($unionConditions as $k => $v){

$selectSql[] = 'select uid,username from members_'.$k.' where uid in('.implode(',',$v).')';

}

mysql_query(implode(' union ',$selectSql));


2、分表前:select uid,username from members where 1 order by friends desc limit ;

这里要按好友数降序排列,我们该怎么办,有一种方式是,分表前,我们需要建立一张索引表,先从索引表根据排序后查询出数据,然后在去查询分表的内容,但是,索引表容易过大,所以还是会成为瓶径,个人认为还有一种方案,启用redis的zset数据结构来专门存储friends的排序,因为zset自带排序光环。但是增加了业务更新和插入数据的业务逻辑,并且数据也产生冗余,但还是建议尽量增加where条件定位查询表。zset请自行百度查询

分表后:

1、从redis里获取根据friends排序好的uid

$uids = $redis->zRange("user_friends",$limitStart,$recordNums);

2、对uid取模,使用union联接查询mysql

3、因为取模后查询出来的数据是无序的,对查询出来的数据,在业务层上需要排序

4、输出数据


3、分表前:select uid,username from members where uid in(10,20,30,40) and friends > 20;

分表后:跟1的方式一样,分析where后面的查询,分解成select uid,username from members_1 where uid in(10,20,) and friends > 20 union....


4、分表前:select uid,username from members where username = “xxxx”

这种方式,个人建议,针对where后面的查询条件并且是字符串型的,使用开源的sphinx建立索引。

分表后:从sphinx根据username查询出uid,然后去mysql取数据


5、分表后的join查询,尽量修改成多条sql语句查询。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值