Redis常用数据结构使用(一)

118 阅读5分钟

说明

github:github.com/mxAge18/not… 个人网站:www.invokerx.com/2022/03/15/…

几种常用redis命令操作学习记录

  • string
  • list
  • set
  • hash
  • zset

其他类型

  • geospatial
  • bitmaps
  • hyperloglog

当前说明string list常用命令

正文

一、String

String 类型的常用场景:

  • 计数器
  • 统计多单位的数量 (set userId:xxxx:article_number 0)
  • 粉丝数
  • 对象缓存存储 (setex)

基本操作:set get append strlen

  • set 设置缓存

    set key value [EX seconds] [PX milliseconds] [NX|XX]
    
  • get 返回缓存数据的value

  • append 向key对应的value进行append操作

    • append时,如果指定key不存在,创建一个新key(功能就跟set类似了)
  • strlen返回指定key的value的长度

###############################################################################################
127.0.0.1:6379> set redis_test_string_1 xuexiredis 					#set a string key-value value is "xuexiredis"
OK
127.0.0.1:6379> get redis_test_string_1 										#get a key's value
"xuexiredis"
127.0.0.1:6379> APPEND redis_test_string_1 _append_string  	#append string to string type key value data
(integer) 24
127.0.0.1:6379> get redis_test_string_1                     #get a key's value after append
"xuexiredis_append_string"
127.0.0.1:6379> APPEND redis_test_string_2 append_not_exist_string    #append string to an non-exist key, equal set new key
(integer) 23
127.0.0.1:6379> get redis_test_string_2
"append_not_exist_string"
127.0.0.1:6379> strlen redis_test_string_2 # strlen, return the string's length
(integer) 23
127.0.0.1:6379>

#########################################################################

计数器:incr decr incrby decrby

计数相关操作 incr decr是增加1 或减少1

incrby decrby 用法:incrby|decrby key increment/decrement 可设定增减的步长

######################
# incr
# decr
# incrby
# decrby
127.0.0.1:6379> set redis_test_views 0    #counter increase and decrease;"incr" and "decr" Step lengths is 1
OK
127.0.0.1:6379> get redis_test_views
"0"
127.0.0.1:6379> incr redis_test_views
(integer) 1
127.0.0.1:6379> incr redis_test_views
(integer) 2
127.0.0.1:6379> decr redis_test_views
(integer) 1

127.0.0.1:6379> incrby redis_test_views 100  #"incrby" and "decrby" Step lengths can be set
(integer) 101
127.0.0.1:6379> decrby redis_test_views 20   #"incrby"/"decrby" key increment/decrement
(integer) 81
127.0.0.1:6379>
############################################################################ 

截取value:getrange setrange

getrange 获取字符串指定索引范围内的字符:对not set 的key返回 ""

setrange 对指定范围内的字符进行替换

######################
# GETRANGE
# SETRANGE
127.0.0.1:6379> GETRANGE key start end # Intercept string
127.0.0.1:6379> GETRANGE redis_test_string_1 0 1 # "redis_test_string_1" is "xuexiredis"
"xu"
127.0.0.1:6379> GETRANGE redis_test_string_1 0 -1
"xuexiredis_append_string"

127.0.0.1:6379> SETRANGE key offset value  #Replace string with new string
127.0.0.1:6379> setrange redis_test_string_1 0 tihuan # xuexiredis_append_string
(integer) 24
127.0.0.1:6379> get redis_test_string_1 # tihuanedis_append_string
"tihuanedis_append_string"
127.0.0.1:6379> setrange redis_test_string_1 20 tihuan
(integer) 26
127.0.0.1:6379> get redis_test_string_1
"ttihuandis_append_sttihuan"
127.0.0.1:6379> setrange redis_test_string_1 27 haha  #offset + replacment string > strlen
(integer) 31
127.0.0.1:6379> get redis_test_string_1 							#offset > strlen
"ttihuandis_append_sttihuan\x00haha"
###############################################################################################

过期时间 setex setnx

setex (set with expire)

setnx (set if not exist)

127.0.0.1:6379> setex key seconds value 
127.0.0.1:6379> setex redis_ttl_30 30 setttl_is_30s
OK
127.0.0.1:6379> ttl redis_ttl_30
(integer) 19
127.0.0.1:6379> ttl redis_ttl_30
(integer) 1
127.0.0.1:6379> ttl redis_ttl_30
(integer) -2
127.0.0.1:6379> get redis_ttl_30
(nil)

127.0.0.1:6379> setnx key3 "redis is remote dic service"
(integer) 1
127.0.0.1:6379> setnx key3 "mongo db"
(integer) 0
127.0.0.1:6379> get key3
"redis is remote dic service"
127.0.0.1:6379>
#########################################################################

多个key操作:mset mget msetnx

######################
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> mset k1 v1 k2 v2 k3 v3 # multi set key value
OK
127.0.0.1:6379[2]> mset k1 v11 k4 v4  # multi set exist key will rewrite the value
OK  
127.0.0.1:6379[2]> keys *
1) "k3"
2) "k4"
3) "k2"
4) "k1"
127.0.0.1:6379[2]> mget k1 k2 k3 k4
1) "v11"
2) "v2"
3) "v3"
4) "v4"
127.0.0.1:6379[2]> msetnx k1 v111 k5 v5 # multi set exist key will not success 原子性操作
OK  
(integer) 0
127.0.0.1:6379[2]> keys *
1) "k3"
2) "k4"
3) "k2"
4) "k1"
127.0.0.1:6379[2]> mget k1 k2 k3 k4
1) "v11"
2) "v2"
3) "v3"
4) "v4"


# object set
# set an key with attribute instead of use json, more effective
127.0.0.1:6379[2]> set user:1 {name:maxu,age:20}
OK
127.0.0.1:6379[2]> get user:1
"{name:maxu,age:20}"
127.0.0.1:6379[2]> mset user:1:name maxu user:1:age 20
OK
127.0.0.1:6379[2]> mget user:1:name user:1:age
1) "maxu"
2) "20"
#########################################################################

获取后更新 getset

获取key的旧value后设置成新value

一开始key不存在返回nil并设置新值

######################
# getset
127.0.0.1:6379[2]> getset user:1:name nancy
"maxu"
127.0.0.1:6379[2]> get user:1:name
"nancy"

二、List

用来实现栈 队列 阻塞队列

  • 实际上是一个链表 left Node right; left right都可以插入 删除
  • 如果不存在进行新建链表
  • 移除了所有值,空链表
  • 在两边插入或者删除效率高。

lpush rpush

127.0.0.1:6379[2]> lpush key value [value ...]
127.0.0.1:6379[2]> rpush key value [value ...]
127.0.0.1:6379[2]> lrange key start stop
#########################################################################
127.0.0.1:6379[2]> lpush list one two three
(integer) 3
127.0.0.1:6379[2]> lrange list 0 1
1) "three"
2) "two"
127.0.0.1:6379[2]> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379[2]> rpush list rightval
(integer) 4
127.0.0.1:6379[2]> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "rightval"

lrange

lrange返回list内指定索引范围的values(只是扫描返回数据,不是出栈操作,list内的数据不改变)

lpop rpop

127.0.0.1:6379[2]> lpop key
127.0.0.1:6379[2]> rpop key
#########################################################################
127.0.0.1:6379[2]> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "rightval"
127.0.0.1:6379[2]> lpop list
"three"
127.0.0.1:6379[2]> lrange list 0 -1
1) "two"
2) "one"
3) "rightval"
127.0.0.1:6379[2]> rpop list
"rightval"
127.0.0.1:6379[2]> lrange list 0 -1
1) "two"
2) "one"

lindex

根据index获取list内的value

127.0.0.1:6379[2]> lindex key index
#########################################################################
127.0.0.1:6379[2]> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379[2]> lindex list 1
"one"
127.0.0.1:6379[2]> lindex list 0
"two"

llen

list的长度

127.0.0.1:6379[2]> llen key
127.0.0.1:6379[2]> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379[2]> llen list
(integer) 2

lrem

批量从list中remove若干个value

127.0.0.1:6379[2]> lrem key count value


127.0.0.1:6379[2]> lpush one two three four three four five
(integer) 6
127.0.0.1:6379[2]> lrange one 0 -1
1) "five"
2) "four"
3) "three"
4) "four"
5) "three"
6) "two"
127.0.0.1:6379[2]> lrem one 1 three # remove from left , remove 1 element which val =  "three"
(integer) 1
127.0.0.1:6379[2]> lrange one 0 -1
1) "five"
2) "four"
3) "four"
4) "three"
5) "two"


127.0.0.1:6379[2]> flushdb
OK
127.0.0.1:6379[2]>  lpush one two three four three four five
(integer) 6
127.0.0.1:6379[2]>  lrange one 0 -1
1) "five"
2) "four"
3) "three"
4) "four"
5) "three"
6) "two"
127.0.0.1:6379[2]> lrem one -1 three  # remove from right , remove 1 element which val =  "three"
(integer) 1
127.0.0.1:6379[2]> lrange one 0 -1
1) "five"
2) "four"
3) "three"
4) "four"
5) "two"

ltrim

127.0.0.1:6379[2]> ltrim key start stop

127.0.0.1:6379[2]> rpush mylist "one" "two" "three"
(integer) 3
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379[2]> ltrim mylist 0 1
OK
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "one"
2) "two"

rpop lpush

127.0.0.1:6379[2]> rpoplpush source destination

127.0.0.1:6379[2]> lrange mylist 0 -1
1) "one"
2) "two"
127.0.0.1:6379[2]> rpoplpush mylist yourlist
"two"
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "one"
127.0.0.1:6379[2]> lrange yourlist 0 -1
1) "two"

lset

lset replace list type data, index's value

127.0.0.1:6379[2]> exists testlist
(integer) 0
127.0.0.1:6379[2]> lset testlist 0 item
(error) ERR no such key
127.0.0.1:6379[2]> lpush testlist first_val
(integer) 1
127.0.0.1:6379[2]> exists testlist
(integer) 1
127.0.0.1:6379[2]> lset testlist 0 item
OK
127.0.0.1:6379[2]> lrange testlist 0 -1
1) "item"
127.0.0.1:6379[2]> lset testlist 1 other
(error) ERR index out of range

linsert

用于在列表的元素前或者后插入元素。当指定元素不存在于列表中时,不执行任何操作。

当列表不存在时,被视为空列表,不执行任何操作。

如果 key 不是列表类型,返回一个错误。

redis> linsert key BEFORE|AFTER pivot value
# 将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。

问题:list中存在重复值时想要insert元素到redis,防止重复插入可使用linsert

127.0.0.1:6379[2]> lpush mylist "hello" "world"
(integer) 2
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "world"
2) "hello"
127.0.0.1:6379[2]> linsert mylist before "hello" mid
(integer) 3
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "world"
2) "mid"
3) "hello"
127.0.0.1:6379[2]>
# 问题:如果list中存在多个重复值怎么办 : 最左的第一个匹配的值进行插入
127.0.0.1:6379[2]> lpush mylist hello
(integer) 4
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "hello"
2) "world"
3) "mid"
4) "hello"
127.0.0.1:6379[2]> linsert mylist before "hello" mid2
(integer) 5
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "mid2"
2) "hello"
3) "world"
4) "mid"
5) "hello"
127.0.0.1:6379[2]> linsert mylist after "hello" mid2
(integer) 6
127.0.0.1:6379[2]> lrange mylist 0 -1
1) "mid2"
2) "hello"
3) "mid2"
4) "world"
5) "mid"
6) "hello"