2、向6台数据库server均发送一个查询请求,然后对所有查询结果进行汇总,再处理分页逻辑。
3、建立一个总数据库,只负责维护主键和必要的索引,以供分页查询。
4、使用redis维护一个主键序列,分页 *** 作就是截取该序列的一部分,其结果就是主键id集合。拿到id后便可以映射到多台mysql服务器上查询数据了。但毕竟数据被分布式存储了,取到完整结果集必须要多次、多台的数据库访问,这个肯定是避免不了。
注:“多台”数据库访问的问题无解,但同台“多次”数据库访问的问题可以通过程序优化。
简介:实现用户信息的分页查询
1. 实现思路
list链表键存储用户ID,用于分页查询,同时用于查询用户总数,key为personid。
hset用户保存用户详细信息,格式为下:
key-->person:userid
value-->id userid name 张三 age 33
2. 增加用户
[java] view plain copy
static Jedis jedis = new Jedis("192.168.0.144")
static void saveUser(){
String id = new Random().nextInt(10000) + ""
Map<String, String> map = new HashMap<String, String>()
map.put("id", id)
map.put("age", new Random().nextInt(70) + "")
map.put("name", "张三"+new Random().nextInt(10000) + "")
jedis.rpush("personid", id) // 保存用户id
jedis.hmset("person:" + id, map) // 保存用户信息
}
3. 修改用户
同增加用户。
4. 删除用户
关键代码如下:
[java] view plain copy
jedis.del("person:" + id)
5. 获得用户详细信息
[java] view plain copy
static Map<String, String> getUserInfo(String id){
return jedis.hgetAll("person:" + id)
}
6.分页获得用户列表
[java] view plain copy
static void getUserList(){
Long count = jedis.llen("personid") // 用户总数
List<String> idList = jedis.lrange("personid", 5, 10)
for(String id : idList){
System.out.println(jedis.hgetAll("person:" + id))
}
}
在实际业务中我们会将一些热数据缓存到redis里面,这时候数据量比较大的话,我们就要对这些热数据进行分页,分页的方式有2种:
第一:从redis拿出所有数据后,再做内存分页(不推荐),热点数据小的时候可以这样做,性能相差不是很大,但是当数据量大的时候,分页期间就会占用大量内存,或撑爆;
第二:基于redis的数据结构做缓存分页,这里又分2种
①:基于redis的list数据结构,直接通过list的数据结构,用range方法可以进行分页,在数据量大的时候,性能也很可观,但是当存在接口高并发访问时,这个list可能会无限延长,且里面的数据会存在很多重复,这就会影响到正常的业务(不是很推荐);
②:基于redis的ZSet数据结构,通过Zset这个有序集合我们也可以做分页,同样也是用range方法,但是这里比较麻烦的是在初始化数据的时候Zset必须存放TypedTuple类型的数据,这个类型是一个value和score的键值对,具体可以查百度,这个score的生成比较麻烦我这边测试时用的是当前数据在这个list的位置,然后Zset是根据这个score值来排序的,默认是从小到大;用这个的好处是,即使在高并发情况下Zset中也不会存在重复数据从而影响正常的业务;而且分页效率也和list结构差不多;
③:用hash和Zset来一起实现;这个是问了一个朋友和得知的,Zset中存储有序的id字段,通过分页后拿到id,然后再用id去hash中取,感觉应该效率相差不大的,只是中间多了层从hash结构取,还需要维护又一个hash;(为何这样做我也不清楚);
贴一张我测试list和ZSet的结果图
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)