page contents

Redis 的 4大数据类型,写得非常好!

NoSQL 开发中或多或少都会用到,也是面试必问知识点。 最近这几天的面试每一场都问到了,但是感觉回答的并不好,还有很多需要梳理的知识点,这里通过几篇 Redis 笔记整个梳理一遍。

attachments-2021-03-Bzxa8Guo603f3f46e722c.png

NoSQL 开发中或多或少都会用到,也是面试必问知识点。

最近这几天的面试每一场都问到了,但是感觉回答的并不好,还有很多需要梳理的知识点,这里通过几篇 Redis 笔记整个梳理一遍。


Redis 的八大数据类型

官网可查看命令:http://www.redis.cn/commands....

Redis-key

`127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name xxx
OK
127.0.0.1:6379> keys *
1"name"127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> keys *
1"age"2"name"127.0.0.1:6379> exists name  # 判断key 是否存在(integer) 1
127.0.0.1:6379> exists name1
(integer) 0
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
1"age"127.0.0.1:6379> set name yyy
OK
127.0.0.1:6379> expire name 10  # 设置key的过期时间,单位是秒(integer) 1
127.0.0.1:6379> ttl name  # 查看当前key的剩余过期时间(integer) 7
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> type age  # 查看当前key的类型string
127.0.0.1:6379>
`

Redis 有以下 8 种数据类型

1、String(字符串)

`127.0.0.1:6379> set key1 v1   #设置值OK
127.0.0.1:6379> get key1"v1"127.0.0.1:6379> append key1 "hello"  # 追加值,如果不存在,相当于 set key(integer) 7
127.0.0.1:6379> get key1"v1hello"127.0.0.1:6379> strlen key1  # 获取字符串长度(integer) 7
127.0.0.1:6379>
`

自增、自减

`127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views"0"127.0.0.1:6379> incr views  # 自增 1(integer) 1
127.0.0.1:6379> get views"1"127.0.0.1:6379> decr views       # 自减 1(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views"-1"127.0.0.1:6379> incrby views 10  # 设置步长、自增 10 (integer) 9
127.0.0.1:6379> decrby views 5      # 设置步长、自减 5(integer) 4
`

字符串范围

`127.0.0.1:6379> set key1 "hello,world!"OK
127.0.0.1:6379> get key1"hello,world!"127.0.0.1:6379> getrange key1 0 3  # 截取字符串[0, 3]"hell"127.0.0.1:6379> getrange key1 0 -1  # 获取全部的字符串,和 get key一样"hello,world!"127.0.0.1:6379>
`

替换:

`127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2"abcdefg"127.0.0.1:6379> setrange key2 1 xx
(integer) 7
127.0.0.1:6379> get key2"axxdefg"127.0.0.1:6379>
`

setex(set with expire):设置过期时间

和setnx(set if not exist):不存在再设置(在分布式锁中会经常使用)

`127.0.0.1:6379> setex key3 30 "hello"  # 设置 30 秒后过期OK
127.0.0.1:6379> ttl key3     # 剩余过期时间(integer) 25
127.0.0.1:6379> setnx mykey "redis"   # mykey 不存在时设置成功(integer) 1
127.0.0.1:6379> keys *
1"key2"2"key1"3"views"4"mykey"127.0.0.1:6379> setnx mykey "mongoDB"  # mykey 存在时设置失败(integer) 0
127.0.0.1:6379> get mykey     # mykey 值不变"redis"127.0.0.1:6379>
`

mset 和 mget

`127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3  # 同时设置多个值OK
127.0.0.1:6379> keys *
1"k1"2"k3"3"k2"127.0.0.1:6379> mget k1 k2 k3   # 同时获取多个值1"v1"2"v2"3"v3"127.0.0.1:6379> msetnx k1 v1 k4 v4       # msetnx 是一个原子性的操作,要么一起成功,要么都失败(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379>
`

对象

`set user:1 {name:zhangsan, age:3}     # 设置一个 user:1 对象 值为 json  字符来保存一个对象127.0.0.1:6379mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379mget user:1:name user:1:age
1) "zhangsan"2) "2"127.0.0.1:6379>

`

getset:先 get 再 set

`127.0.0.1:6379> getset db redis  # 如果不存在值,则返回 nil(nil)
127.0.0.1:6379> get db"redis"127.0.0.1:6379> getset db mongodb  # 如果存在值,获取原来的值,并设置新的值"redis"127.0.0.1:6379> get db"mongodb"127.0.0.1:6379>

`

String 的使用场景:value 除了是字符串以外还可以是数字

  • 计数器
  • 统计多单位的数量
  • 粉丝数
  • 对象缓存存储

2、List(列表)

基本的数据类型,列表。

在 Redis 中可以把 list 用作栈、队列、阻塞队列。

list 命令多数以 l开头。

`127.0.0.1:6379> lpush list one   # 将一个值或者多个值,插入到列表的头部(左)(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three 
(integer) 3
127.0.0.1:6379lrange list 0 -1   # 查看全部元素1"three"2"two"3"one"127.0.0.1:6379lrange list 0 1    # 通过区间获取值1"three"2"two"127.0.0.1:6379> rpush list right   # 将一个值或者多个值,插入到列表的尾部(右)(integer) 4
127.0.0.1:6379lrange list 0 -1
1"three"2"two"3"one"4"right"127.0.0.1:6379>
`

弹出 pop

`127.0.0.1:6379lrange list 0 -1
1"!"2"world"3"world"4"hello"127.0.0.1:6379> lpop list  # 移除list的第一个元素"!"127.0.0.1:6379lrange list 0 -1
1"world"2"world"3"hello"127.0.0.1:6379> rpop list   # 移除list的第一个元素"hello"127.0.0.1:6379lrange list 0 -1
1"world"2"world"127.0.0.1:6379>

`

索引 Lindex

`127.0.0.1:6379lrange list 0 -1
1"hjk"2"world"3"world"127.0.0.1:6379lindex list 1  # 通过下标获取list中的某一个值"world"127.0.0.1:6379lindex list 0"hjk"127.0.0.1:6379>
`

Llen 长度:

`127.0.0.1:6379> llen list
(integer) 3
127.0.0.1:6379>
`

移除指定的值:

`127.0.0.1:6379lrange list 0 -1
1"hjk"2"world"3"world"127.0.0.1:6379> lrem list 1 world  # 移除list集合中指定个数的value,精确匹配(integer) 1
127.0.0.1:6379lrange list 0 -1
1"hjk"2"world"127.0.0.1:6379> lpush list hjk
(integer) 3
127.0.0.1:6379lrange list 0 -1
1"hjk"2"hjk"3"world"127.0.0.1:6379> lrem list 2 hjk
(integer) 2
127.0.0.1:6379lrange list 0 -1
1"world"127.0.0.1:6379>
`

trim 截断

`127.0.0.1:6379lrange mylist 0 -1
1"hello1"2"hello2"3"hello3"4"hello4"127.0.0.1:6379> ltrim mylist 1 2 # 通过下标截取指定长度,这个list已经被破坏了,截断之后只剩下截断后的元素OK
127.0.0.1:6379lrange mylist 0 -1
1"hello2"2"hello3"127.0.0.1:6379>
`

rpoplpush :移除列表的最后一个元素,将他移动到新的列表中。

`127.0.0.1:6379lrange mylist 0 -1
1"hello1"2"hello2"3"hello3"127.0.0.1:6379> rpoplpush mylist myotherlist  # 移除列表的最后一个元素,将他移动到新的列表中。"hello3"127.0.0.1:6379> lrange mylist 0 -1  # 查看原来的列表1"hello1"2"hello2"127.0.0.1:6379> lrange myotherlist 0 -1  # 查看目标列表中,确实存在该值1"hello3"127.0.0.1:6379>
`

lset:将列表中指定下标的值替换为另一个值,更新操作

`127.0.0.1:6379> exists list  # 判断这个列表是否存在(integer) 0
127.0.0.1:6379lset list 0 item  # 如果不存在的话,更新会报错(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379lrange list 0 0 
1"value1"127.0.0.1:6379lset list 0 item  # 如果存在,更新当前下标的值OK
127.0.0.1:6379lset list 1 other  # 如果不存在的话,更新会报错(error) ERR index out of range
127.0.0.1:6379>
`

linsert:将某个具体的value插入到列表中某个元素的前面或者后面

`127.0.0.1:6379lrange mylist 0 -1
1"hello1"2"hello2"127.0.0.1:6379linsert mylist before "hello2" hello
(integer) 3
127.0.0.1:6379lrange mylist 0 -1
1"hello1"2"hello"3"hello2"127.0.0.1:6379linsert mylist after "hello2" hello
(integer) 4
127.0.0.1:6379lrange mylist 0 -1
1"hello1"2"hello"3"hello2"4"hello"127.0.0.1:6379>
`

小结

  • list 实际上是一个链表,前后都可以插入
  • 如果key不存在,创建新的链表
  • 如果移除了所有的值,空链表,也代表不存在
  • 在两边插入或者改动值,效率最高。

3、Set (集合)

`127.0.0.1:6379> sadd myset "hello"  # set 集合中添加元素(integer) 1
127.0.0.1:6379> sadd myset "world"(integer) 1
127.0.0.1:6379> smembers myset      # 查看指定Set的所有值1"world"2"hello"127.0.0.1:6379> sismember myset hello  # 判断某一个值是不是在set中(integer) 1
127.0.0.1:6379> sismember myset hello1
(integer) 0
127.0.0.1:6379>
`
`127.0.0.1:6379> scard myset  # 获取集合中的个数(integer) 2
127.0.0.1:6379> sadd myset "hello2"(integer) 1
127.0.0.1:6379> smembers myset   
1"world"2"hello2"3"hello"127.0.0.1:6379> srem myset hello   # 移除元素(integer) 1
127.0.0.1:6379> smembers myset
1"world"2"hello2"127.0.0.1:6379>

`

`127.0.0.1:6379> smembers myset
1"kkk"2"world"3"hjk"4"hello2"127.0.0.1:6379> srandmember myset   # 随机抽取一个元素"hjk"127.0.0.1:6379> srandmember myset"hello2"127.0.0.1:6379> srandmember myset 2   # 随机抽取指定个数的元素1"world"2"hello2"127.0.0.1:6379> srandmember myset 2
1"hello2"2"hjk"127.0.0.1:6379>
`
`127.0.0.1:6379> smembers myset
1"kkk"2"world"3"hjk"4"hello2"127.0.0.1:6379> spop myset  # 随机删除元素"hjk"127.0.0.1:6379> smembers myset
1"kkk"2"world"3"hello2"127.0.0.1:6379> spop myset"hello2"127.0.0.1:6379> smembers myset
1"kkk"2"world"127.0.0.1:6379>
`
`127.0.0.1:6379> smembers myset
1"kkk"2"world"127.0.0.1:6379> sadd myset2 set2
(integer) 1
127.0.0.1:6379> smove myset myset2 "kkk"   # 将一个特定的值,移动到另一个set集合中(integer) 1
127.0.0.1:6379> smembers myset
1"world"127.0.0.1:6379> smembers myset2
1"kkk"2"set2"127.0.0.1:6379>
`
`127.0.0.1:6379> smembers key1
1"b"2"a"3"c"127.0.0.1:6379> smembers key2
1"e"2"d"3"c"127.0.0.1:6379> sdiff key1 key2   # 差集1"b"2"a"127.0.0.1:6379> sinter key1 key2         # 交集1"c"127.0.0.1:6379> sunion key1 key2  # 并集1"e"2"a"3"c"4"d"5"b"
`

4、Hash(哈希)

也是 key - value 形式的,但是value 是一个map。

`127.0.0.1:6379> hset myhash field xxx  # set 一个 key-value(integer) 1
127.0.0.1:6379> hget myhash field   # 获取一个字段值"xxx"127.0.0.1:6379> hmset myhash field1 hello field2 world  # set 多个 key-valueOK
127.0.0.1:6379> hmget myhash field field1 field2   # 获取多个字段值1"xxx"2"hello"3"world"127.0.0.1:6379> hgetall myhash    # 获取全部的数据1"field"2"xxx"3"field1"4"hello"5"field2"6"world"
`
`127.0.0.1:6379> hdel myhash field1  # 删除指定的key,对应的value也就没有了(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field"2) "xxx"3) "field2"4) "world"127.0.0.1:6379>
`
`127.0.0.1:6379> hlen myhash  # 获取长度(integer) 2
127.0.0.1:6379> hexists myhash field1   # 判断指定key是否存在(integer) 0
127.0.0.1:6379> hexists myhash field2
(integer) 1
127.0.0.1:6379> hkeys myhash  # 获取所有的key1) "field"2"field2"127.0.0.1:6379> hvals myhash  # 获取所有的value1) "xxx"2"world"127.0.0.1:6379>

`

`127.0.0.1:6379> hset myhash field3 5
(integer) 1
127.0.0.1:6379> hincrby myhash field3 1  # 指定增量(integer) 6
127.0.0.1:6379> hincrby myhash field3 -1
(integer) 5
127.0.0.1:6379> hsetnx myhash field4 hello  # 如果不存在则可以设置(integer) 1
127.0.0.1:6379> hsetnx myhash field4 world  # 如果存在则不能设置(integer) 0
127.0.0.1:6379>

Hash 适合存储经常变动的对象信息,String 更适合于存储字符串。


attachments-2021-03-fycI9Xie603f3f6c23e69.jpg

  • 发表于 2021-03-03 15:14
  • 阅读 ( 707 )
  • 分类:数据库

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1320 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章