栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

02-Redis常用数据类型

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

02-Redis常用数据类型

文章目录
    • 简介
      • 概述
      • 常用数据类型
    • String类型操作实践
      • incr/incrby
      • decr/decrby
      • append
      • strlen
      • mset/mget
      • 小节面试分析
    • Hash类型应用实践
      • hset/hget
      • hmset/hmget
      • hincrby
      • hexists
      • hdel
      • hkeys/hvals
      • hlen
      • 小节面试分析
    • List类型应用实践
      • lpush
      • rpush
      • del
      • linsert
      • lset
      • lrem
      • ltrim
      • lpop
      • rpop
      • llen
      • lindex
      • rpoplpush
      • 小节面试分析
    • Set类型应用实践
      • sadd
      • smembers
      • spop
      • scard
      • smove
      • sunion
      • 小节面试分析
    • 总结(Summary)

简介 概述

Redis作为一种key/value结构的数据存储系统,为了便于对数据进行进行管理,提供了多种数据类型。然后,基于指定类型存储我们项目中产生的数据,例如用户的登陆信息,购物车信息,商品详情信息等等。

常用数据类型

Reids中基础数据结构包含字符串、散列,列表,集合,有序集合。工作中具体使用哪种类型要结合具体场景。

String类型操作实践

字符串类型是redis中最简单的数据类型,它存储的值可以是字符串,其最大字符串长度支持到512M。基于此类型,可以实现博客的字数统计,将日志不断追加到指定key,实现一个分布式自增iid,实现一个博客的的点赞操作等

incr/incrby

当存储的字符串是整数时,redis提供了一个实用的命令 incr,其作用是让当前键值递增,并返回递增后的值。
incr key 按照默认步长(默认为1)进行递增
incrby key decrement 按照指定步长进行递增
语法:incr key

127.0.0.1:6379> set num 1
OK
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> keys *
1) "num"	
127.0.0.1:6379> incr num
(integer) 3
127.0.0.1:6379>

说明,如果num不存在,则自动会创建,如果存在自动+1。

指定增长系数

语法:INCRBY key increment

127.0.0.1:6379> incrby num 2
(integer) 5
127.0.0.1:6379> incrby num 2
(integer) 7
127.0.0.1:6379> incrby num 2
(integer) 9
127.0.0.1:6379>
decr/decrby

减少指定的整数
decr key 按照默认步长(默认为1)进行递减
decrby key decrement 按照指定步长进行递减

127.0.0.1:6379> incr num
(integer) 10
127.0.0.1:6379> decr num
(integer) 9
127.0.0.1:6379> decrby num 3
(integer) 6
127.0.0.1:6379>
append

向尾部追加值。
如果键不存在,则创建该键,其值为写的value,即相当于set key value。
返回值是追加后字符串的总长度。
语法:append key value

127.0.0.1:6379> keys *
1) "test"
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> append test "abc"
(integer) 6
127.0.0.1:6379> get test
"123abc"
127.0.0.1:6379>
strlen

字符串长度
返回数据的长度,如果键不存在则返回0。注意,如果键值为空串,返回值也是0。
语法:strlen key

127.0.0.1:6379> get test
"123abc"
127.0.0.1:6379> strlen test
(integer) 6
127.0.0.1:6379> strlen tnt
(integer) 0
127.0.0.1:6379> set tnt ""
OK
127.0.0.1:6379> strlen tnt
(integer) 0
127.0.0.1:6379> exists tnt
(integer) 1
127.0.0.1:6379>
mset/mget

同时设置/获取多个键值
语法:
mset key value
mget key

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> mset a 1 b 2 c 3
OK
127.0.0.1:6379> mget a b c
1) "1"
2) "2"
3) "3"
127.0.0.1:6379>
小节面试分析
  • 博客的字数统计如何实现?(strlen)
  • 如何将审计日志不断追加到指定key?(append)
  • 你如何实现一个分布式自增id?(incr-雪花算法)
  • 如何实现一个博客的的点赞操作?(incr,decr)
Hash类型应用实践

Redis散列类型相当于Java中的HashMap,实现原理跟HashMap一致,一般用于存储对象信息,存储了字段(field)和字段值的映射,一个散列类型可以包含最多232-1个字段。

hset/hget

赋值/取值

hset命令不区分插入和更新操作,当执行插入操作时hset命令返回1,当执行更新操作时返回0。

语法结构

hset key field value
hget key field
hmset key field value 
hmget key field 
hgetall key

hset 和 hget 赋值和取值

127.0.0.1:6379> hset user username chenchen
(integer) 1
127.0.0.1:6379> hget user username
"chenchen"
127.0.0.1:6379> hset user username chen
(integer) 0
127.0.0.1:6379> keys user
1) "user"
127.0.0.1:6379> hgetall user
1) "username"
2) "chen"
127.0.0.1:6379> 
127.0.0.1:6379> hset user age 18
(integer) 1
127.0.0.1:6379> hset user address "xi'an"
(integer) 1
127.0.0.1:6379> hgetall user
1) "username"
2) "chen"
3) "age"
4) "18"
3) "address"
4) "xi'an"
127.0.0.1:6379>
hmset/hmget

语法结构

hmset key field value 
hmget key field 
hgetall key

hmset 和 hmget 设置和获取对象属性

127.0.0.1:6379> hmset person username tony age 18
OK
127.0.0.1:6379> hmget person age username
1) "18"
2) "tony"
127.0.0.1:6379> hgetall person
1) "username"
2) "tony"
3) "age"
4) "18"
127.0.0.1:6379>

注意:上面 hmget 字段顺序可以自行定义

hincrby
127.0.0.1:6379> hdecrby article total 1		#执行会出错
127.0.0.1:6379> hincrby article total -1	#没有hdecrby自减命令
(integer) 1
127.0.0.1:6379> hget article total			#获取值
hexists

属性是否存在

127.0.0.1:6379> hexists killer
(error) ERR wrong number of arguments for 'hexists' command
127.0.0.1:6379> hexists killer a
(integer) 0
127.0.0.1:6379> hexists user username
(integer) 1
127.0.0.1:6379> hexists person age
(integer) 1
127.0.0.1:6379>
hdel

删除属性

127.0.0.1:6379> hdel user age
(integer) 1
127.0.0.1:6379> hgetall user
1) "username"
2) "chen"
127.0.0.1:6379> hgetall person
1) "username"
2) "tony"
3) "age"
4) "18"
127.0.0.1:6379>
hkeys/hvals

只获取字段名 hkeys 或字段值 hvals

127.0.0.1:6379> hkeys person
1) "username"
2) "age"
127.0.0.1:6379> hvals person
1) "tony"
2) "18"
hlen

获取元素个数

127.0.0.1:6379> hlen user
(integer) 1
127.0.0.1:6379> hlen person
(integer) 2
127.0.0.1:6379>
小节面试分析
  • 发布一篇博客需要写内存吗?(需要,hmset)
  • 浏览博客内容会怎么做?(hmget)
  • 如何判定一篇博客是否存在?(hexists)
  • 删除一篇博客如何实现?(hdel)
  • 分布式系统中你登录成功以后是如何存储用户信息的?(hmset)
List类型应用实践

Redis的list类型相当于java中的linkedList,其原理就就是一个双向链表。支持正向、反向查找和遍历等操作,插入删除速度比较快。
经常用于实现热销榜,最新评论等的设计。

List命令
序号命令作用示例
1lpush在头(左边)部添加多个key值lpush names ‘张三’,lpush names ‘李四’
2lrange获取指定范围的key的值lrange names 0 10
3blpop移除并获取第一个元素,并设置阻塞时间blpop names 10
4brpop移除并获取尾部元素,并设置阻塞时间brpop names 10
5lindex通过索引获取列表中的key值lindex names 1
6linsert在张三前|后插入tom值linsert names before|after ‘张三’ ‘tom’
7llen获取列表长度llen names
8lpop移出并获取第一个元素lpop names
9lpushx将多值插入到已存在的列表头部lpushx names lili
10lrem移除指定个数的值,count表示方向lrem ages 2 10
11lset修改指定索引的值lset ages 1 11
12ltrim保留修剪内部的数据ltrim ages 1 -1
13rpop移出尾部元素,并返回rpop ages
14rpush在尾(右边)部添加多个key值rpush ages 14 15
15rpushx将多值插入到已存在的列表头部rpushx names hahah
16rpoplpush将尾部的值移到新key中rpoplpush names newname
lpush

在 key 对应 list 的头部添加字符串元素

redis 127.0.0.1:6379> lpush mylist "world" "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist 0 -1  #0表示第一个,-1表示最后一个
1) "hello"
2) "world"
redis 127.0.0.1:6379>

其中,Redis Lrange 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推

rpush

在 key 对应 list 的尾部添加字符串元素

redis 127.0.0.1:6379> rpush mylist2 "hello" "world"
(integer) 2
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) "hello"
2) "world"
redis 127.0.0.1:6379>
del
redis 127.0.0.1:6379> del mylist
linsert

在 key 对应 list 的特定位置之前或之后添加字符串元素

redis 127.0.0.1:6379> rpush mylist3 "hello" "world"
(integer) 2
redis 127.0.0.1:6379> linsert mylist3 before "world" "there"
(integer) 3
redis 127.0.0.1:6379> lrange mylist3 0 -1
1) "hello"
2) "there"
3) "world"
redis 127.0.0.1:6379>
lset

设置 list 中指定下标的元素值(一般用于修改操作)

redis 127.0.0.1:6379> rpush mylist4 "one"
(integer) 1
redis 127.0.0.1:6379> rpush mylist4 "two"
(integer) 2
redis 127.0.0.1:6379> rpush mylist4 "three"
(integer) 3
redis 127.0.0.1:6379> lset mylist4 0 "four"
OK
redis 127.0.0.1:6379> lset mylist4 -2 "five"
OK
redis 127.0.0.1:6379> lrange mylist4 0 -1
1) "four"
2) "five"
3) "three"
redis 127.0.0.1:6379>
lrem

从 key 对应 list 中删除 count 个和 value 相同的元素

当count>0时,按从头到尾的顺序删除

redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist5 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist5 2 "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) "foo"
2) "hello"
redis 127.0.0.1:6379>

当count<0时,按从尾到头的顺序删除

redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist6 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist6 -2 "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist6 0 -1
1) "hello"
2) "foo"
redis 127.0.0.1:6379>

当count=0时,删除全部

redis 127.0.0.1:6379> rpush mylist7 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist7 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist7 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist7 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist7 0 "hello"
(integer) 3
redis 127.0.0.1:6379> lrange mylist7 0 -1
1) "foo"
redis 127.0.0.1:6379>
ltrim

保留指定 key 的值范围内的数据

redis 127.0.0.1:6379> rpush mylist8 "one"
(integer) 1
redis 127.0.0.1:6379> rpush mylist8 "two"
(integer) 2
redis 127.0.0.1:6379> rpush mylist8 "three"
(integer) 3
redis 127.0.0.1:6379> rpush mylist8 "four"
(integer) 4
redis 127.0.0.1:6379> ltrim mylist8 1 -1
OK
redis 127.0.0.1:6379> lrange mylist8 0 -1
1) "two"
2) "three"
3) "four"
redis 127.0.0.1:6379>
lpop

从 list 的头部删除元素,并返回删除元素

redis 127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
redis 127.0.0.1:6379> lpop mylist
"hello"
redis 127.0.0.1:6379> lrange mylist 0 -1
1) "world"
redis 127.0.0.1:6379>
rpop

从 list 的尾部删除元素,并返回删除元素:

redis 127.0.0.1:6379> lrange mylist2 0 -1
1) "hello"
2) "world"
redis 127.0.0.1:6379> rpop mylist2
"world"
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) "hello"
redis 127.0.0.1:6379>
llen

返回 key 对应 list 的长度:

redis 127.0.0.1:6379> llen mylist5
(integer) 2
redis 127.0.0.1:6379>
lindex

返回名称为 key 的 list 中 index 位置的元素:

redis 127.0.0.1:6379> lrange mylist5 0 -1
1) "three"
2) "foo"
redis 127.0.0.1:6379> lindex mylist5 0
"three"
redis 127.0.0.1:6379> lindex mylist5 1
"foo"
redis 127.0.0.1:6379>
rpoplpush

从第一个 list 的尾部移除元素并添加到第二个 list 的头部,最后返回被移除的元素值,整个操作是原子的.如果第一个 list 是空或者不存在返回 nil:
rpoplpush lst1 lst1
rpoplpush lst1 lst2

小节面试分析
  • 如何基于redis实现一个队列结构?(lpush/rpop)
  • 如何基于redis实现一个栈结构?(lpush/lpop)
  • 如何基于redis实现一个阻塞式队列?(lpush/brpop)
  • 如何实现秒杀活动的公平性?(先进先出-FIFO)
  • 通过list结构实现一个消息队列(顺序)吗?(可以,FIFO->lpush,rpop)
  • 用户注册时的邮件发送功能如何提高其效率?(邮件发送是要调用三方服务,底层通过队列优化其效率,队列一般是list结构)
  • 如何动态更新商品的销量列表?(卖的好的排名靠前一些,linsert)
  • 商家的粉丝列表使用什么结构实现呢?(若注意顺序,则使用list结构,若不注意顺序,则使用set结构)
Set类型应用实践

Redis的Set类似Java中的HashSet,是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

sadd

添加元素,重复元素添加失败,返回0

127.0.0.1:6379> sadd name tony
(integer) 1
127.0.0.1:6379> sadd name hellen
(integer) 1
127.0.0.1:6379> sadd name rose
(integer) 1
127.0.0.1:6379> sadd name rose
(integer) 0
smembers

获取内容

127.0.0.1:6379> smembers name
1) "hellen"
2) "rose"
3) "tony"
127.0.0.1:6379>
spop

移除并返回集合中的一个随机元素

127.0.0.1:6379> smembers set1
1) "amoeba"
2) "redis"
3) "rabbitmq"
4) "nginx"
127.0.0.1:6379> spop set1
"rabbitmq"
127.0.0.1:6379> spop set1
"nginx"
127.0.0.1:6379> smembers set1
1) "amoeba"
2) "redis"
scard

获取成员个数

127.0.0.1:6379> scard name
(integer) 3
smove

移动一个元素到另外一个集合中

127.0.0.1:6379> sadd set1 amoeba nginx redis
(integer) 3
127.0.0.1:6379> sadd set2 hadopp spark rabbitmq
(integer) 3
127.0.0.1:6379> smembers set1
1) "amoeba"
2) "redis"
3) "nginx"
127.0.0.1:6379> smembers set2
1) "hadopp"
2) "spark"
3) "rabbitmq"
127.0.0.1:6379> smove set2 set1 rabbitmq
(integer) 1
127.0.0.1:6379> smembers set1
1) "amoeba"
2) "redis"
3) "rabbitmq"
4) "nginx"
127.0.0.1:6379> smembers set2
1) "hadopp"
2) "spark"
127.0.0.1:6379>
sunion

两个集合的并集

127.0.0.1:6379> sunion set1 set2
1) "redis"
2) "nginx"
3) "rabbitmq"
4) "amoeba"
5) "hadopp"
6) "spark"
小节面试分析
  • 朋友圈的点赞功能你如何实现?(sadd,srem,smembers,scard)
  • 如何实现一个网站投票统计程序?
  • 你知道微博中的关注如何实现吗?
总结(Summary)

本章节主要是对redis中的常用数据类型存储结构,基本操作进行了分析和实践,结合指令特性理解其应用场景,

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/305926.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号