Redis-03、常用数据类型:string、 hash、 list

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。对应Java中的:String、 HashMap、LinkedList、 HashSet、 TreeSet

String(字符串)

string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。

string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

  • 存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型
  • 存储数据的格式:一个存储空间保存一个数据
  • 存储内容:通常使用字符串,如果字符串以纯整数的形式展示,可以作为数字操作使用

string 作为数值操作

  • string在redis内部存储默认就是一个字符串,当遇到增减类操作incr, decr时会转成数值型进行计算。
  • redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发
    带来的数据影响。
  • 注意: 按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis 数值上限范围,将报错。
    9223372036854775807( java中long型数据最大值, Long.MAX_VALUE)

基础命令

命令 功能
set key value 添加/修改数据,set已有的key即为覆盖修改
get key 获取数据
del key 删除数据
mset key1 value1 key2 value2 … 添加/修改多个数据
mget key1 key2 … 获取多个数据
strlen key 获取数据字符个数(字符串长度)
append key value 追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
>SET username chenheng
OK
>get username
"chenheng"
>del username
(integer) 1

>mset a 1 b 2 c 3
OK
>mget a b c
1) "1"
2) "2"
3) "3"

>strlen username
(integer) 8

>append a BCDE
(integer) 5			//追加成功,返回字符总个数

在set/get 单条 和 set/get 多条,在数据较多时,建议使用mset、 mget

扩展命令1

扩展命令 功能
incr key 数值数据自增1
incrby key increment 设置数值数据增加指定范围的值
incrbyfloat key increment 设置数值数据增加指定范围的小数值
decr key 数值数据自减1
decrby key increment 设置数值数据减少指定范围的值
//b=2
>incr b
(integer) 3

>incrby b 10
(integer) 13

>incrbyfloat b 0.5
"13.5"

扩展命令2

命令 功能
setex key seconds value 设置数据的值,并以秒为单位设置 key 的生存时间
psetex key milliseconds value 设置数据的值,并以毫秒为单位设置 key 的生存时间
setnx key value key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。
>setex a 5 name
OK
>get a
(nil)

注:在时效性数据存活期间,set 同名的普通数据,时效性数据的时效性就会被消除

应用场景

业务场景1
大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键 id 必须保证统一性
,不能重复。 Oracle 数据库具有 sequence 设定,可以解决该问题,但是 MySQL数据库并不具有类似的机
制,那么如何解决?

解决方案:设置key自增、自减

业务场景2

“最强女生”启动海选投票,只能通过微信投票,每个微信号每 4 小时只能投1票。
电商商家开启热门商品推荐,热门商品不能一直处于热门期,每种商品热门期维持3天, 3天后自动取消热门。
新闻网站会出现热点新闻,热点新闻最大的特征是时效性,如何自动控制热点新闻的时效性?

解决方案:设置数据具有指定的生命周期

扫描二维码关注公众号,回复: 10891262 查看本文章

业务场景3

主页高频访问信息显示控制,例如新浪微博大V主页显示粉丝数与微博数量

解决方案

在redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定定时刷新策略即可
user:id:3506728370:fans → 12210947
user:id:3506728370:blogs → 6164
user:id:3506728370:focuss → 83
在redis中以json格式存储大V用户信息,定时刷新(也可以使用hash类型)
user:id:3506728370 → {"id":3506728370,"name":"春晚","fans":12210862,"blogs":6164, "focus":83}

string的应用

  • redis用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性
    此方案适用于所有数据库,且支持数据库集群
  • redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作
  • redis应用于各种结构型和非结构型高热度数据访问加速
  • redis 应用于限时按次结算的服务控制

hash

Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
对象类数据的存储如果具有较频繁的更新需求操作会显得笨重 :

image-20200412114504577

  • 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息
  • 需要的存储结构:一个存储空间保存多个键值对数据
  • hash类型:底层使用哈希表结构实现数据存储
  • hash存储结构优化
    • 如果field数量较少,存储结构优化为类数组结构
    • 如果field数量较多,存储结构使用HashMap结构

基本命令

命令 功能
hset key field value 添加/修改一个字段的数据
hget key field 获取一个字段的数据
hgetall key 获取全部的key及value
hdel key field1 [field2...] 删除key
hmset key field1 value1 [field2 value2 …] 添加/修改多个字段数据
hmget key field1 [field2 …] 获取多个数据
hlen key 获取哈希表中字段的数量
hexists key field 获取哈希表中是否存在指定的字段
>  hset user name zhangsan
(integer) 1
>  hget user name
"zhangsan"
>  hset user age 12
(integer) 1
> hset user grade 3
(integer) 1

>  hget user name
"zhangsan"

> hgetall user
1) "name"
2) "zhangsan"
3) "age"
4) "12"
5) "grade"
6) "3"

>  hdel user grade
(integer) 1

> hmset user grade 3 class 2
OK

> hmget user grade class
1) "3"
2) "2"

> hlen user
(integer) 4

> hexists user class
(integer) 1

扩展命令

命令 功能
hkeys key 获取哈希表中所有的字段名
hvals key 获取哈希表中所有的字段值
hincrby key field increment 设置指定字段的数值数据增加指定范围的值
hincrbyfloat key field increment 设置指定字段的数值数据增加指定范围的值
hsetnx key field value 没有指定字段就添加
> hkeys user
1) "name"
2) "age"
3) "grade"
4) "class"

> hvals user
1) "zhangsan"
2) "12"
3) "3"
4) "2"

> hincrby user grade 4
(integer) 7

> hincrbyfloat user age 0.5
"12.5"

> hsetnx user age 10
(integer) 0
> hset user house 100
(integer) 1

注意事项

  • hash类型下的value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到,
    对应的值为( nil)
  • 每个 hash 可以存储 232 - 1 个键值对
  • hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存
    储大量对象而设计的,切记不可滥用,更不可以将hash作为对象列表使用
  • hgetall 操作可以获取全部属性,如果内部field过多,遍历整体数据效率就很会低,有可能成为数据访问
    瓶颈

应用场景

业务场景1

电商网站购物车设计与实现

业务分析

分析购物车的redis存储模型,添加、浏览、更改数量、删除、清空

解决方案

  • 以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息
  • 将商品编号作为field,购买数量作为value进行存储
  • 添加商品:追加全新的field与value
  • 浏览:遍历hash
  • 更改数量:自增/自减,设置value值
  • 删除商品:删除field
  • 清空:删除key

为了加速了购物车商品信息的呈现

  • 每条购物车中的商品记录保存成两条field

  • field1专用于保存购买数量
    命名格式:商品id:nums
    保存数据:数值

  • field2专用于保存购物车中显示的信息,包含文字描述,图片地址,所属商家信息等
    命名格式:商品id:info
    保存数据: json

    该字段的数据从一个商品信息独立hash中读取

    使用hsetnx key field value动态创建和扩展独立hash

业务场景2

双11活动日,销售手机充值卡的商家对移动、联通、电信的30元、 50元、 100元商品推出抢购活动,每种商
品抢购上限1000张

解决方案

  • 以商家id作为key
  • 将参与抢购的商品id作为field
  • 将参与抢购的商品数量作为对应的value
  • 抢购时使用降值的方式控制产品数量

hash的应用

  • redis 应用于购物车数据存储设计
  • redis 应用于抢购,限购类、限量发放优惠卷、激活码等业务的数据存储设计

hash和string的比较

string存储:整体性,数据要么一次刚更新,要么一次性读取,主要用户呈现数据
hash: 更新灵活

list

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

  • 数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
  • 需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序
  • list类型:保存多个数据,底层使用双向链表存储结构实现
image-20200412131751107 image-20200412131835596

基本命令

命令 功能
lpush key value1 [value2] …… 从左边添加/修改数据
rpush key value1 [value2] …… 从右边添加/修改数据
lrange key start stop 获取指定范围的列表数据
lindex key index 获取指定下标的列表元素
llen key 获取列表的长度
lpop key 从左侧获取并移除一个数据
rpop key 从右侧获取并移除一个数据
> lpush students zhangsan lisi wangwu
(integer) 3

> lrange students 0 -1
1) "wangwu"
2) "lisi"
3) "zhangsan"

> lindex students 1
"lisi"

> llen students
(integer) 3

> lpop students
"wangwu"
> rpop students
"zhangsan"

扩展命令1

命令 功能
blpop key1 [key2] timeout 规定时间内从左侧获取并移除一个数据
brpop key1 [key2] timeout 规定时间内从右侧获取并移除一个数据
brpoplpush source destination timeout 从列表中取出最后一个元素,并插入到另外一个列表的头部; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
> blpop students 5
1) "students"
2) "lisi"

lrange list1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
5) "300"
6) "200"
7) "100"
> lpush list2 d e f g
(integer) 4
> brpoplpush list1 list2 5
"100"
> lrange list2 0 -1
1) "100"
2) "g"
3) "f"
4) "e"
5) "d"

扩展命令2

命令 功能
lrem key count value 从左侧移除指定数量的指定数据
> lrem list1 1 200
(integer) 1

应用场景

业务场景1

微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息,如果取消点赞,移除对应好友信息

解决方案

移除指定数据

业务场景2

twitter、新浪微博、腾讯微博中个人用户的关注列表需要按照用户的关注顺序进行展示,粉丝列表需要将最近关注的粉丝列在前面。
新闻、资讯类网站如何将最新的新闻或资讯按照发生的时间顺序展示?
企业运营过程中,系统将产生出大量的运营数据,如何保障多台服务器操作日志的统一顺序输出?

解决方案

  • 依赖list的数据具有顺序的特征对信息进行管理
  • 使用队列模型解决多路信息汇总合并的问题
  • 使用栈模型解决最新消息的问题

list的应用

  • redis 应用于具有操作先后顺序的数据控制
  • redis 应用于最新消息展示

注意事项

  • list中保存的数据都是string类型的,数据总容量是有限的,最多232 - 1 个元素 (4294967295)。
  • list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作
  • 获取全部数据操作结束索引设置为-1
  • list可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载
  • redis 应用于基于时间顺序的数据操作,而不关注具体时间

猜你喜欢

转载自www.cnblogs.com/sout-ch233/p/12721526.html