精华内容
下载资源
问答
  • Redis分页查询

    2019-11-14 17:16:48
    思路:采用 Redis 的有序集合,通过分数来对元素排序,我们可以将用户的 ID 等键存在该有序集合中,将用户的真实信息存在一个 Hash 中,通过分数取出对应页码的 ID,然后根据 ID 批量取出用户信息. 代码演示 public...

    思路:采用 Redis 的有序集合,通过分数来对元素排序,我们可以将用户的 ID 等键存在该有序集合中,将用户的真实信息存在一个 Hash 中,通过分数取出对应页码的 ID,然后根据 ID 批量取出用户信息.

    原文链接:详情请点击

    代码演示

    public function page(Request $request, $page) {
    	$key = 'shuxiaoyuan';
    	$value = 'shuxiaoyuan:info';
    
    	// 采用Redis管道命令,批量写入99999条数据,为啥不是十万,你猜
    	$data = Redis::pipeline(function ($pipe) use ($key, $value) {
    		for ($i = 1; $i < 100000; $i  ) {
    			$pipe->zadd($key, $i, 'user_' . $i);
    			$pipe->hset($value, 'user_' . $i, str_random());
    		}
    	});
    	
    	// 分页显示
    	$pageSize = 10;
    	$limit_s = ($page - 1) * $pageSize;
    	$limit_e = ($limit_s   $pageSize) - 1;
    	$range = Redis::zrevrange($key, $limit_s, $limit_e, 'withscores'); // 分数从大到小
    	$count = Redis::zcard($key); //总条数
    	$pageCount = ceil($count / $pageSize); //总页数
    	
    	$keys = array_keys($range);
    	
    	$pageList = Redis::hmget($info, $keys);
    	
    	$data = array(
    		'data' => $pageList, //需求数据
    		'page' => array(
    			'page'      => $page, //当前页数
    			'pageSize'  => $pageSize, //每页多少条
    			'count'     => $count, //记录总数
    			'pageCount' => $pageCount //总页数
    		)
    	);
    		
    	dd($data);
    }
    
    展开全文
  • redis 分页查询

    2016-04-15 15:04:00
    zset 分页查询: 格式: <zsetKey> <searchKey> <pageNo> 参数说明:{ zsetKey :有序集键 key1 searchKey : 查询内容 argv1 pageNo :当前页号(默认为1) argv2 pageSize :页面大小(默认为15) argv3 } ...

    算法:

    容器使用的是zset,因为当zset中所有的分值都为0时集合将按ascii码排序。所以利用这点只要找出其范围再

    使用zrange获取就行了。取得该范围的方式是通过在集合中插入两个搜索关键字的临界值,如搜索abc,那么这个

    临界值为abb{ 和abc{ 。将其插入到集合中再搜索出基位置。最后将其删除(参考:<<redis in action>>)

    下面是分页lua脚本:

    --[[
    zset 分页查询: 
     格式: <zsetKey> <searchKey> <pageNo> <pageSize>
     参数说明:{
    	zsetKey   :有序集键 key1   
    	searchKey : 查询内容 argv1
    	pageNo    :当前页号(默认为1) argv2
        pageSize  :页面大小(默认为15) argv3
     }
     示例: evalsha 232fd51614574cf0867b83d384a5e898cfd24e5a 1 my:zset abc
    ]]
    local zsetKey,searchKey,pageNo,pageSize = KEYS[1],ARGV[1],tonumber(ARGV[2]),tonumber(ARGV[3])
    local content = ",-/0123456789@_abcdefghijklmnopqrstuvwxyz{"
    
    if(not zsetKey) then return {} end
    if(not pageNo or pageNo < 1) then pageNo = 1 end
    if(not pageSize or pageSize < 1) then pageSize = 15 end
    
    local recTotal = redis.call('zcard',zsetKey)
    if(recTotal == 0) then return {} end  --空集合
    
    --找出查询关键字在zset中的位置
    local function getRange(searchKey)
    	local lastChar = string.sub(searchKey,-1,-1)
        local temp = string.find(content,lastChar)-1
    	local startStr = string.sub(searchKey,1,-2)..string.sub(content,temp,temp)..string.sub(content,-1,-1)
    	local endStr = searchKey..string.sub(content,-1,-1)
    	redis.call('zadd',zsetKey,0,startStr)
    	redis.call('zadd',zsetKey,0,endStr)
        local starp1,starp2 = redis.call('zrank',zsetKey,startStr) , redis.call('zrank',zsetKey,endStr)
        redis.call('zrem',zsetKey,startStr)
        redis.call('zrem',zsetKey,endStr)
    	return starp1,starp2-2
    end
    
    local startPosition,endPosition = 0,recTotal
    if(searchKey ~= "") then
    	startPosition,endPosition = getRange(searchKey);
    end
    
    startPosition = startPosition + (pageNo-1)*pageSize
    endPosition = math.min(startPosition + pageSize-1,endPosition)
    
    
    if(startPosition > recTotal or endPosition < 0) then return {} end --没有找到要查询的结果
    
    return redis.call('zrange',zsetKey,startPosition,endPosition)



    --[[
    zset 查询总数: 
     格式: <zsetKey> <searchKey> 
     参数说明:{
    	zsetKey   :有序集键 key1   
    	searchKey : 查询内容 argv1
     }
     示例: evalsha 232fd51614574cf0867b83d384a5e898cfd24e5a 1 my:zset abc
    ]]
    local zsetKey,searchKey = KEYS[1],ARGV[1]
    local content = ",-/0123456789@_abcdefghijklmnopqrstuvwxyz{"
    
    if(not zsetKey) then return 0 end
    local recTotal = redis.call('zcard',zsetKey)
    if(searchKey == "") then return recTotal end  
    
    --找出查询关键字在zset中的位置
    local function getRange(searchKey)
    	local lastChar = string.sub(searchKey,-1,-1)
        local temp = string.find(content,lastChar)-1
    	local startStr = string.sub(searchKey,1,-2)..string.sub(content,temp,temp)..string.sub(content,-1,-1)
    	local endStr = searchKey..string.sub(content,-1,-1)
    	redis.call('zadd',zsetKey,0,startStr)
    	redis.call('zadd',zsetKey,0,endStr)
        local starp1,starp2 = redis.call('zrank',zsetKey,startStr) , redis.call('zrank',zsetKey,endStr)
        redis.call('zrem',zsetKey,startStr)
        redis.call('zrem',zsetKey,endStr)
    	return starp1,starp2-2
    end
    
    local startPosition,endPosition = getRange(searchKey);
    
    if(startPosition > recTotal or endPosition < 0) then return 0 end --没有找到要查询的结果
    
    return endPosition - startPosition + 1;



    上面只支持英文查询(小写)

    转载于:https://my.oschina.net/u/2552286/blog/660536

    展开全文
  • 基于SortedSet的分页查询缓存方案首先想到的解决方法是使用@see ListOperations不再根据分页条件使用多个key,而是使用一个key,也不分页将全部的数据缓存到redis中,然后按照分页条件使用range(key,...

    我们都知道,通过缓存查询的结果,可以极大的提升系统的服务能力,以及降低底层服务或者是数据库的压力。对于有分页条件的缓存,我们也可以按照不同的分页条件来缓存多个key。

    28337fcc4525271128200b5d4619a026.png

    基于SortedSet的分页查询缓存方案

    首先想到的解决方法是使用@see ListOperations不再根据分页条件使用多个key,而是使用一个key,也不分页将全部的数据缓存到redis中,然后按照分页条件使用range(key,start,limit)获取分页的结果。 (推荐学习:Redis视频教程)

    这个会导致一个问题,当缓存失效时,并发的写缓存会导致出现重复数据,所以想到通过使用set来处理并发时的重复数据,@see ZSetOperations

    代码逻辑如下:range(key,start,limit)按照分页条件获取缓存,命中则直接返回

    缓存未命中,查询(没有分页条件)数据库或是调用(没有分页)底层接口

    add(key,valueScoreMap)写入缓存,expire设置缓存时间

    当需要清理缓存时,直接删除key,如果是因为数据新增和删除,可以add(key,value,score)或remove(key,value)

    redis中会按照score分值升序排列map中的数据,一般的,score分值是sql语句的order by filedA的filedA的值,这样能保证数据一致性

    但是这种方式也存在一定问题:

    这个key缓存的value确实是热数据,但可能只有少数数据被频繁使用其余的可能根本就未被使用,比如数据有100页,实际可能只会用到前10页,这也会导致缓存空间的浪费,如果使用了redis虚拟内存,也会有一定影响

    sql查询由原来的分页查询变成了不分页查询,缓存失效后,系统的处理能力较之前会有下降,尤其是对于大表

    更多Redis相关技术文章,请访问Redis入门教程栏目进行学习!

    展开全文
  • 每个主题下的用户的评论组装好写入Redis中,每个主题会有一个topicId,每一条评论会和topicId关联起来,大致的数据模型如下: (推荐学习:Redis视频教程){ topicId: 'xxxxxxxx', comments: [ { username: 'niuniu', ...

    a8ecac5363f69e198bd45ebcaa4932c0.png

    每个主题下的用户的评论组装好写入Redis中,每个主题会有一个topicId,每一条评论会和topicId关联起来,大致的数据模型如下: (推荐学习:Redis视频教程){ topicId: 'xxxxxxxx', comments: [ { username: 'niuniu', createDate: 1447747334791, content: '在Redis中分页', commentId: 'xxxxxxx', reply: [ { content: 'yyyyyy' username: 'niuniu' }, ... ] }, ... ]}

    将评论数据从MySQL查询出来组装好存到Redis后,以后每次就可以从Redis获取组装好的评论数据,从上面的数据模型可以看出数据都是key-value型数据,无疑要采用hash进行存储,但是每次拿取评论数据时需要分页而且还要按createDate字段进行排序,hash肯定是不能做到分页和排序的。

    那么,就挨个看一下Redis所支持的数据类型:

    1、String: 主要用于存储字符串,显然不支持分页和排序。

    2、Hash: 主要用于存储key-value型数据,评论模型中全是key-value型数据,所以在这里Hash无疑会用到。

    3、List: 主要用于存储一个列表,列表中的每一个元素按元素的插入时的顺序进行保存,如果我们将评论模型按createDate排好序后再插入List中,似乎就能做到排序了,而且再利用List中的LRANGE key start stop指令还能做到分页。

    嗯,到这里List似乎满足了我们分页和排序的要求,但是评论还会被删除,就需要更新Redis中的数据,如果每次删除评论后都将Redis中的数据全部重新写入一次,显然不够优雅,效率也会大打折扣,如果能删除指定的数据无疑会更好,而List中涉及到删除数据的就只有LPOP和RPOP这两条指令,但LPOP和RPOP只能删除列表头和列表尾的数据,不能删除指定位置的数据,(备注:其实还有 LREM命令可以做到删除,但是非常不方便),而且当存在接口高并发访问时,这个list可能会无限延长,且里面的数据会存在很多重复,这就会影响到正常的业务,所以List也不太适合。

    4、Set: 主要存储无序集合,无序!排除。

    5、SortedSet: 主要存储有序集合,SortedSet的添加元素指令ZADD key score member [[score,member]…]会给每个添加的元素member绑定一个用于排序的值score,SortedSet就会根据score值的大小对元素进行排序,在这里就可以将createDate当作score用于排序。

    SortedSet中的指令ZREVRANGE key start stop又可以返回指定区间内的成员,可以用来做分页,SortedSet的指令ZREM key member可以根据key移除指定的成员,能满足删评论的要求,所以,SortedSet在这里是最适合的(时间复杂度O(log(N)))。

    所以,需要用到的数据类型有SortSet和Hash,SortSet用于做分页排序,Hash用于存储具体的键值对数据。SortSet结构中将每个主题的topicId作为set的key,将与该主题关联的评论的createDate和commentId分别作为set的score和member,commentId的顺序就根据createDate的大小进行排列。

    当需要查询某个主题某一页的评论时,就可主题的topicId通过指令zrevrange topicId (page-1)×10 (page-1)×10+perPage这样就能找出某个主题下某一页的按时间排好顺序的所有评论的commintId。page为查询第几页的页码,perPage为每页显示的条数。

    当找到所有评论的commentId后,就可以把这些commentId作为key去Hash结构中去查询该条评论对应的内容。

    这样就利用SortSet和Hash两种结构在Redis中达到了分页和排序的目的。

    当然,也可以直接只使用SrotedSet类型,而不使用Hash类型,直接将评论存放在member中。

    但为什么要将评论和排序放到不同的类型里?其中的好处是,可以对评论设置不同的排序类型,比如按时间的正反序,点赞的正反序,查看次数的正反序等。而这样只需要维护不同的SrotedSet排序,不需要维护多套评论的内容了。

    展开全文
  • redis分页查询案例

    2020-07-10 17:18:34
    redis分页查询利用到了sortset 和 hash的两个数据类型,这两个互相配合使用才能完美的完成分页,思想都在都在代码中 1.初始逻辑 @Override public List<User> selectAll() { long page = 2; long ...
  • 偶然在代码中发现一个接口,接口定义说是分页查询,但逻辑实现是Redis。不太理解,Redis怎么分页?后来看到一篇文章,然后了解了。 1、Zrevrange实现 通过SortedSet的zrevrange topicId (page-1)×10 (page-1)...
  • 1.使用$redis->zAdd("key",1,'user1');添加10条数据查询结果:192.168.1.120:0>zrange key 0 -11) user_12) user_23) user_3;4) user_4;5) user_5;6) user_6;7) user_7;8) user_8;9) user_9;10) user_10;php...
  • 实现Redis分页查询 java

    千次阅读 2019-03-10 21:48:23
    https://blog.csdn.net/weixin_36563269/article/details/80804916 https://blog.csdn.net/hadoopxsy/article/details/80009413 https://blog.csdn.net/tianluke1234/article/details/80431222 https://blog.csdn.net/jack85986370/article/details/51483872实现分页查询...
  • java redis 分页查询数据

    千次阅读 2019-03-27 18:35:28
    context = new ClassPathXmlApplicationContext("spring-monkey.xml", "spring-redis-cluster.xml"); RedisService redisService = context.getBean("redisServiceImpl", RedisService.class); int pageNum = 2;...
  • Redis 分页排序查询

    万次阅读 多人点赞 2016-05-23 18:45:08
    Redis是一个高效的内存数据库,它支持包括String、List、Set、SortedSet和Hash等数据类型的存储,在Redis中通常根据数据的key查询其value值,Redis没有条件查询,在面对一些需要分页或排序的场景时(如评论,时间线...
  • redis 分页

    2019-01-23 22:00:00
    redis 分页 127.0.0.1:6379> rpush a 0 (integer) 1 127.0.0.1:6379> rpush a 1 (integer) 2 127.0.0.1:6379> rpush a 2 (integer) 3 127.0.0.1:6379> rpush a 3 (integer) 4 127.0.0.1:...
  • Redis分页排序查询

    2016-11-26 18:55:05
    http://www.cnblogs.com/wuxl360/p/5465670.htmlhttp://www.th7.cn/db/nosql/201605/189525.shtml
  • Redis 分页

    2017-04-14 10:36:00
    Redis提供了有序集合SortedSet,使用ZRANGE key start stop,可以查询指定范围。 那么我们可以把id存到有许集合里,直接按照id或者创建时间来排序。 再把详细的数据存到hashmap里,从集合里取出id后,再从hashmap里...
  • Redis分页存储

    2021-04-20 16:53:44
    在实际业务中我们会将一些热数据缓存到redis里面,这时候数据量比较大的话,我们就要对这些热数据进行分页分页的方式有2种: 第一:从redis拿出所有数据后,再做内存分页(不推荐),热点数据小的时候可以这样做,...
  • 基于redis分页和排序设计(根据redis的数据类型设计)
  • redis分页 排序

    千次阅读 2018-03-26 15:27:08
    Redis是一个高效的内存数据库,它支持包括String、List、Set、SortedSet和Hash等数据类型的存储,在Redis中通常根据数据的key查询其value值,Redis没有条件查询,在面对一些需要分页或排序的场景时(如评论,时间线...
  • Redis 分页/排序

    2018-01-11 09:40:35
    Redis是一个高效的内存数据库,它支持包括String、List、Set、SortedSet和Hash等数据类型的存储,在Redis中通常根据数据的key查询其value值,Redis没有条件查询,在面对一些需要分页或排序的场景时(如评论,时间线...
  • Redis实现分页查询

    千次阅读 2018-08-03 21:46:39
    在我们开发项目的过程中,经常会对数据做分页展示,如果每次请求都去查询数据库,当访问量增大时,势必会加重数据库的负载,降低数据库性能。然而,有些数据的是极少变动的,或者说变动的频率不是很高,这时如果将...
  • Spring Boot整合Redis实现分页查询

    千次阅读 2020-03-13 16:03:32
    Spring Boot整合Redis实现分页查询 1、Demo描述: **目标:**心理医生可以到问题社区中,根据问题的提问日期,分页查询问题。 效果设计: ​将mysql中热点问题(日期靠前的问题)保存在Redis缓存中。假设热点...
  • 初学redis分页缓存方法实现

    千次阅读 2019-03-06 14:06:10
    初学redis分页缓存方法实现 使用缓存技术一般是在不经常增删改查的数据,我们可以使用缓存技术将第一次请求访问的数据缓存到redis中保存起来,后来的请求的时候首先查询redis数据库是否查询到这些数据,如果存在,...
  • python redis 分页

    2019-02-21 09:27:00
    使用SortedSet 和 Hash 进行分页处理 import json from redis import ConnectionPool, StrictRedis import time, datetime pool = ConnectionPool(host='192.168.2.122', port=6379, db=0) # 由于redis输出数据...
  • 关于redis查询分页

    2019-06-25 18:13:26
    但是实际业务中又需要实现分页查询,于是只能借助sortedset来实现。 比如商品表由hash类型存储 good:10001 good:10002 … good:20000 后面的数字为good_id zadd good_set 1 10001 zadd good_set 2 10002 … zadd ...
  • 怎么用redis实现分页缓存,比如有1000页数据,只缓存当前页的后两页,点击到其他页时再缓存当前页的后两页。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 35,225
精华内容 14,090
关键字:

redis分页查询

redis 订阅