设为首页 收藏本站
查看: 813|回复: 0

[经验分享] Redis的列表数据类型

[复制链接]

尚未签到

发表于 2016-12-20 06:29:18 | 显示全部楼层 |阅读模式


  • List 类型概述
  • List 的命令操作
  • List 数据类型应用案例

List 类型概述 — List 的基本概念
List是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等,操作中key理解为链表的名字。Redis的list类型其实就是一个每个子元素都是string类型的双向链表。我们可以通过push、pop操作从链表的头部或者尾部添加删除元素, push和pop命令的算法时间复杂度都是O(1),这样list既可以作为栈,又可以作为队列。链表的最大长度是232-1。
List 类型概述 — 底层实现
Redis列表使用两种数据结构作为底层实现:
1. 双端链表
DSC0000.png
2. 压缩列表
因为双端链表占用的内存比压缩列表要多,所以当创建新的列表键时,列表会优
先考虑使用压缩列表作为底层实现,并且在有需要的时候,才从压缩列表实现转
换到双端链表实现。
DSC0001.png
伪代码:
列表:

typedef struct list {
listNode *head;                 // 表头指针
listNode *tail;                     // 表尾指针
unsigned long len;             // 节点数量
void *(*dup)(void *ptr) ;   // 复制函数
void (*free)(void *ptr) ;     // 释放函数
int (*match)(void *ptr, void *key) ;  // 比对函数
}list;
// listNode是双端链表的节点
Typedef   struct  listNode  {
struct listNode *prev;  // 前驱节点
struct listNode *next;  // 后继节点
void *value;   // 值
} listNode;


List 类型概述 — 使用场景
Redis list应用场景非常多,比如:

  • 微博的关注列表
  • 粉丝列表
  • 博客评论
  • 消息队列
  • 取最新 N  个数据的操作
  • 排行榜应用,取 TOP  N 操作

List 的常用命令
LPUSH
语法:LPUSH  key   value
解释:用来向列表左边增加元素,返回值表示增加元素后列表的长度;LPUSH命令还支持同时增加多个元素。
LRANGE
语法:LRANGE  key   start  end
解释:用来获得列表中的某一片段,返回索引从 Start 到 end 之间的所有元素,索引从0开始。LRANGE 命令也支持负索引,-1表示最右边的元素,-2表示最右边倒数第2个元素。
RPUSH
语法:RPUSH  key   value
解释:用来向列表右边增加元素,返回值表示增加元素后列表的长度;RPUSH命令还支持同时增加多个元素。
LINSERT
语法:LINSERT  key   BEFORE | AFTER  pivot  value
解释:此命令首先会在列表中从左到右查找值为pivot的元素,然后根据第2个参数是BEFORE还是AFTER来决定将Value插入到前面还是后面。返回值是插入后元素的个数。
LPOP/RPOP
语法:LPOP/RPOP   key
解释:LPOP命令可以从列表左边弹出一个元素;RPOP从列表右边弹出一个元素。
LPOP和LPUSH配合,RPOP和RPUSH配合可以把列表当作栈使用;LPUSH和RPOP配合,RPUSH和LPOP配合可以把列表当作队列使用。
LREM
语法:LREM  key   count   value
解释:LREM 命令会删除列表中前 count 个值为value 的元素,返回值是实际删除的元素的个数。
当 count >0时,从左边开始删除;
当 count <0时,从右边开始删除;
当 count =0时,删除所有值为 value 的元素;
LTRIM
语法:LTRIM  key   start   end
解释:LTRIM 命令会删除列表中指定索引范围外的所有元素,返回值即指定索引内的元素。LTRIM 命令常和 LPUSH命令一起使用来限制列表中元素的数量,比如记录日志时我们希望只保留最近的100条记录,则每次添加日志时调用一次 LTRIM 命令即可。
RPOPLPUSH
语法:RPOPLPUSH  src   dest
解释:RPOPLPUSH 命令先从 src 列表的右边弹出一个元素,然后将其加入 dest 列表的左边,并返回这个元素的值。当把列表当作队列时,RPOPLPUSH 可以在多个队列中传递数据。当 src 与dest 相同时,此命令会不断的将队尾的元素移动到队首。
LINDEX
语法:LINDEX  key  index
解释:LINDEX 命令用来返回指定索引的元素,索引从0开始。
LSET
语法:LSET key  index  value
解释:将索引为 index 的元素赋值为 value。
LSET
语法:LSET key  index  value
解释:将索引为 index 的元素赋值为 value。
List 数据类型应用案例

  • String 类型存储文章 ID
  • List 类型存储文章 ID
  • List 类型存储文章评论

如何获取文章列表
读取 post:count 键获得博客文章的最大 ID
根据 ID 进行分页(假设每页10条),第 n 页的文章 ID 范围是“最大的文章ID-(n-1)*10”到“max(最大的文章 ID – n*10+1,1)”
对每个ID使用HMGET命令来获取文章的数据,伪代码如下:

页显示10篇文章
$postsPerPage  = 10
# 获得最后发表的文章 ID
$lastPostID = GET posts:count
# 当前页码范围
$start = $lastPostID – ($currentPage - 1) * $postsPerPage
$end = max( $lastPostID – $currentPage  * $postsPerPage +1,1)
# 遍历文章 ID 获取数据
For $i = $start down to $end
# 获取文章的标题和作者并打印出来
post = HMGET post:$i,title,author
Print $post[0]
Print $post[1]

缺点:删除文章时影响页码分布,都需要从最大文章 ID 开始遍历。

List 类型存储文章 ID

使用列表类型键 posts:list 记录文章 ID
LPUSH posts:list  文章ID
LREM    posts:list  1  文章 ID
# 使用 LRANGE 实现分页
$postsPerPage  = 10
$start =  ($currentPage - 1) * $postsPerPage
$end =  $currentPage  * $postsPerPage  - 1
$postsID = LRANGE posts:list,$start,$end
# 获取需要显示文章的 ID 列表
For   each   $id   in   $postsID
$post = HGETALL post:$id
print  文章标题:$post.title
# 使用列表类型键post:文章 ID:comments来存储文章的评论
$serializedComment = serialize($author,$email,$time,$content)
LPUSH  post:42:comments,$serializedComment
读取评论时使用 LRANGE 命令

说明:案例摘抄自极客学院,感谢大牛的分享。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-316536-1-1.html 上篇帖子: 12.redis命令2 下篇帖子: redis 操作命令总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表