Redis 数据结构之 list

前言

Redis作为cache服务器,支持多种数据结构,String、List、Hash、Set、Zset。多种数据结构的存在,使得Redis适用于多种业务,Redis的适用也越发广泛,本文就介绍Redis中最简单的数据结构List的操作命令。


简介

List顾名思义,即链表、队列。即一个key对应的value为一个队列,支持头插、尾插等操作。


命令简介

[LR]PUSH 命令

语法: [LR]PUSH key value1 [value2 ...]
作用: 以头插或尾插方式插入指定key队列中一个或多个元素
返回: 成功返回插入后的队列中元素个数

头插法插入N个元素

127.0.0.1:6379> LPUSH list val1 val2 val3
(integer) 3

尾插法插入N个元素

127.0.0.1:6379> RPUSH list val1 val2 val3
(integer) 6

List中的所有元素

127.0.0.1:6379> LRANGE list 0 -1

  1. "val3"
  2. "val2"
  3. "val1"
  4. "val1"
  5. "val2"
  6. "val3"

[LR]PUSHX 命令

语法: [LR]PUSHX key value
作用: 以头插或尾插方式插入指定key队列中一个或多个元素
返回: 当指定的队列不存在时,返回0,否则插入成功返回插入后队列中的元素个数

向一个不存在的队列中以头插法插入一个节点

127.0.0.1:6379> LPUSHX list value
(integer) 0

向一个存在的队列中以头插法插入一个节点

127.0.0.1:6379> LRANGE list 0 -1

  1. "value"
    127.0.0.1:6379> LPUSHX list value
    (integer) 2

尾插法命令使用方式与头插法类似,此处不做过多介绍


LINSERT 命令

语法: LINSERT key where refVal value
作用: 在已存在的队列key中指定的节点refval位置的前或后插入节点valuewhereafter时在指定节点后插入,before为在指定节点前插入
返回: 队列不存在则返回0;如果指定节点refVal不存在,则不做任何操作并返回-1,否则按照指定位置插入新元素,并返回插入后节点个数

向一个不存在的队列中插入元素

127.0.0.1:6379> LINSERT list after value value1
(integer) 0

向一个已经存在的队列中,指定一个不存在节点位置插入

127.0.0.1:6379> LRANGE list 0 -1

  1. "value"
  2. "value"
    127.0.0.1:6379> LINSERT list after value1 value11
    (integer) -1

向一个已经存在的队列中,指定一个存在的节点位置后插入新元素

127.0.0.1:6379> LINSERT list after value value11
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1

  1. "value"
  2. "value11"
  3. "value"

向一个已经存在的队列中,指定一个存在的节点位置前插入新元素

127.0.0.1:6379> LINSERT list before value value11
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1

  1. "value11"
  2. "value"
  3. "value11"
  4. "value"

注意:当指定的节点在队列中存在多个时,队列按照从头到尾的优先级方式进行匹配


LLEN 命令

语法: LLEN key
作用: 返回队列中元素的个数
返回: 队列不存在返回0,存在则返回队列中元素个数

127.0.0.1:6379> LLEN listlist
(integer) 0
127.0.0.1:6379> LLEN list
(integer) 4


LINDEX 命令

语法: LINDEX key index
作用: 返回指定队列指定下标index处的元素
返回: 队列不存在,返回NULL, index大于队列元素个数,也返回NULL,否则返回对应的节点元素。index如果小于0,则下标逆向遍历

队列不存在的情况

127.0.0.1:6379> LINDEX list111 1
(nil)

指定下标的元素不存在

127.0.0.1:6379> LINDEX list 100
(nil)

获取指定下标的元素

127.0.0.1:6379> LINDEX list 1
"value"


LSET 命令

语法: LSET key index value
作用: 设置队列指定下标出的元素为新值value
返回: 队列不存在或下标越界均返回错误,否则设置成功返货OK

队列不存在

127.0.0.1:6379> LSET listlist 2 value
(error) ERR no such key

下标越界

127.0.0.1:6379> LSET list 100 value
(error) ERR index out of range

成功设置

127.0.0.1:6379> LRANGE list 0 -1

  1. "value11"
  2. "value"
  3. "value11"
  4. "value"
    127.0.0.1:6379> LSET list 0 value123
    OK
    127.0.0.1:6379> LRANGE list 0 -1
  5. "value123"
  6. "value"
  7. "value11"
  8. "value"

[LR]POP 命令

语法: [LR]POP key
作用: 从队列的头或未弹出节点元素(返回该元素并从队列中删除)
返回: 成功则返回元素,失败则返回NULL

失败

127.0.0.1:6379> LPOP listlist
(nil)
127.0.0.1:6379> LPOP list
"value123"
127.0.0.1:6379> RPOP list
"value"


LRANGE 命令

语法: LRANGE key start end
作用: 返回队列指定区间的元素, startend可以为负数,逆向遍历
返回: 成功则返回元素,失败则返回NULL

队列不存在

127.0.0.1:6379> LRANGE listlist 0 -1 s
(empty list or set)

区间指定错误

127.0.0.1:6379> LRANGE list 0 -1

  1. "val6"
  2. "val5"
  3. "val4"
  4. "val3"
  5. "val2"
  6. "val1"
    127.0.0.1:6379> LRANGE list 100 200
    (empty list or set)

获取指定区间的值

127.0.0.1:6379> LRANGE list 2 4

  1. "val4"
  2. "val3"
  3. "val2"
    127.0.0.1:6379> LRANGE list -4 -2
  4. "val4"
  5. "val3"
  6. "val2"

获取整个队列的值

127.0.0.1:6379> LRANGE list 0 -1

  1. "val6"
  2. "val5"
  3. "val4"
  4. "val3"
  5. "val2"
  6. "val1"

LTRIM 命令

语法: LTRIM key start end
作用: 截取队列指定区间的元素,其余元素都删除
返回: 成功则返回OK

测试链表元素值

127.0.0.1:6379> LRANGE list 0 -1

  1. "val6"
  2. "val5"
  3. "val4"
  4. "val3"
  5. "val2"
  6. "val1"

截取指定区间的值

127.0.0.1:6379> LTRIM list 2 4
OK
127.0.0.1:6379> LRANGE list 0 -1

  1. "val4"
  2. "val3"
  3. "val2"

区间值错误

127.0.0.1:6379> LTRIM list -1 0
OK
127.0.0.1:6379> LRANGE list 0 -1
(empty list or set)

区间值错误,导致整个链表为空


LREM 命令

语法: LTRIM key toremove value
作用: 删除队列中指定值的节点,删除方式由toremove决定, toremove大于0则从头遍历删除,最多删除toremove个节点;
toremove小于0则从尾遍历删除,最多删除toremove个节点;
0则删除所有值相同的节点
返回: 返回删除的节点个数

从头删除指定值为val的节点

127.0.0.1:6379> LRANGE list 0 -1

  1. "val"
  2. "val1"
  3. "val"
  4. "val2"
  5. "val"
  6. "val3"
  7. "val"
  8. "val4"
  9. "val"
  10. "val5"
    127.0.0.1:6379> LREM list 3 val
    (integer) 3
    127.0.0.1:6379> LRANGE list 0 -1
  11. "val1"
  12. "val2"
  13. "val3"
  14. "val"
  15. "val4"
  16. "val"
  17. "val5"

队列中值为val的节点数大于需要删除的数,值删除指定数量的节点,如果队列中节点数量不足呢?

127.0.0.1:6379> LREM list 3 val
(integer) 2

127.0.0.1:6379> LRANGE list 0 -1

  1. "val1"
  2. "val2"
  3. "val3"
  4. "val4"
  5. "val5"

toremove小于0的情况与大于0的情况类似,不做介绍,下面简单介绍下为0的情况

127.0.0.1:6379> LRANGE list 0 -1

  1. "val"
  2. "val1"
  3. "val"
  4. "val2"
  5. "val"
  6. "val3"
  7. "val"
  8. "val4"
  9. "val"
  10. "val5"
    127.0.0.1:6379> LREM list 0 val
    (integer) 5
    127.0.0.1:6379> LRANGE list 0 -1
  11. "val1"
  12. "val2"
  13. "val3"
  14. "val4"
  15. "val5"

RPOPLPUSH 命令

语法: RPOPLPUSH srcKey dstKey
作用: 将源队列src的尾部元素插入dst队列的头部
返回: 成功返回插入的元素

源队列

127.0.0.1:6379> LRANGE src 0 -1

  1. "val1"
  2. "val2"
  3. "val3"

目标队列(可以不存在的,如果不存在则会创建一个新的)

127.0.0.1:6379> LRANGE dst 0 -1
(empty list or set)

执行命令

127.0.0.1:6379> RPOPLPUSH src dst
"val3"
127.0.0.1:6379> LRANGE src 0 -1

  1. "val1"
  2. "val2"
    127.0.0.1:6379> LRANGE dst 0 -1
  3. "val3"

B[LR]POP 命令

语法: B[LR]POP key1 [key2 ...] timeout
作用: 从一个或多个队列的头或尾部弹出一个元素,如果指定的队列集合中有一个队列有元素则立即返回数据,否则阻塞等待timeout时间,如果在指定时间内,队列集合中有元素新增,则该操作返回。否则超时时间到,自动返回
返回: 成功返回元素以及元素所属队列,失败返回错误

队列集合中有元素

127.0.0.1:6379> BLPOP src dst 30

  1. "src"
  2. "val1"

队列集合中没有元素且超时

127.0.0.1:6379> BLPOP src dst 30
(nil)
(30.04s)

队列集合中没有元素,阻塞过程中队列集合中新增了元素

127.0.0.1:6379> BLPOP src dst 300

  1. "src"
  2. "kkk"
    (6.67s)
    新增元素操作

127.0.0.1:6379> rpush src kkk
(integer) 1

阻塞的队列尾部操作类似,不做介绍


BRPOPLPUSH 命令

语法: BRPOPLPUSH src dst timeout
作用: 将指定队列src尾部的元素插入到dst头部,如果队列src为空,则操作阻塞timeout时间,在阻塞时间内,如果队列src有新增元素,则将src队列尾部元素插入到dst头部并返回,否则超时返回
返回: 返回操作的元素

源队列不为空

127.0.0.1:6379> BRPOPLPUSH src dst 300
"kkkk"

源队列为空

127.0.0.1:6379> BRPOPLPUSH src dst 300
"jjj"
(11.68s)

新增操作

127.0.0.1:6379> rpush src jjj
(integer) 1


总结

List是用得比较多的数据结构之一,使用list可以轻易的构造队列,比如存储消息队列之类的,以完成FIFOFILO的功能。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容