string和hash数据类型
string和hash数据类型
一、redis 数据存储格式
redis自身是一个Map,其中所有的数据都是采用key:value的形式存储,数据类型指的是存储的value的类型,key部分永远都是字符串

常用数据类型
类型 | 简介 | 特性 | 场景 |
---|---|---|---|
String(字符串) | 二进制安全 | 可以包含任何数据,比如jpg或者,一个键 | --- |
Hash(字典) | 键值对集合,即编程语言中的Map类型 | 适合,并且像数据库中update一个属性一样() | 存储、读取、修改用户属性 |
List(列表) | 链表(双向链表) | 增删快,提供了操作某一段元素的API | 1、最新消息排行等功能(比如朋友圈的时间线) 2、消息队列 |
Set(集合) | 哈希表实现,元素不重复 | 1、添加、删除、查找的 2、为集合 | 1、共同好友 2、利用唯一性,统计访问网站的 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐 |
Sorted Set(zset,有序集合) | 将Set中的元素增加一个权重参数score,元素按score有序排列;元素不重复 | 数据插入集合时,已经进行天然排序 | 1、排行榜 2、带权重的消息队列 l |
二、string
存储的数据:单个数据,最简单数据存储类型,也是最常用的数据存储类型 存储数据的格式:一个存储空间保存一个数据 存储内容:通常使用字符串,

1. string基本操作
添加/修改多个数据
mset key1 valueq key2 value2 …
获取多个数据
mget key1 key2 …

获取数据字符个数(value的长度)
strlen key
追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
append key value

单数据操作和多数据操作有什么区别?

操作同样数据量的情况下,单指令发送和接收次数多。。最好的情况是,
2. string扩展操作
业务场景一
大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键id必须保证统一性,不能重复。Oracle数据库具有sequence设定,可以解决该问题,但是MySQL数据库并不具有类似的机制,那么如何解决?
redis解决方案:
设置数值数据增加指定范围的值
incr key
incrby key 数值(正/负)
incrbyfloat key 数值(正/负)
设置数值数据减少指定范围的值
decr key
decrby key 数值(正/负)


String作为数值操作
- string在redis内部存储默认就是一个字符串,当遇到增减类操作
incr,decr
时会转成数值型进行计算 - redis所有的操作都是原子性的,采用处理所有业务,命令是一个一个执行的,因此。
- 注意:按数值进行操作的数据,如果原始数据,或,将会。9223372036854775807 (java中long型数据最大值,Long.MAX_VALUE)
Tips1:
- redis的单线程、原子性等用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性
- 此方案适用于所有数据库,且支持数据库集群
业务场景二
- “最强女生”启动海选投票,只能通过微信投票,每个微信号每 4 小时只能投1票。
- 电商商家开启热门商品推荐,热门商品不能一直处于热门期,每种商品热门期维持3天,3天后自动取消热门
- 新闻网站会出现热点新闻,热点新闻最大的特征是时效性,如何自动控制热点新闻的时效性。
以上三点场景说的 ,比如我们要实现4小时有效的数据,我们可以给数据设置有效时间为4小时,时间过了就删除该数据,用户可以继续投票
setex key 秒 数值 # 秒
psetex key 毫秒 数值 # 毫秒


Tips 2:
- redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作
业务场景三
主页高频访问信息显示控制,例如新浪微博大V主页显示粉丝数与微博数量需要实时刷新

redis中可以以两种方式存储这些数据

第一种方式,但是;第二种方式,但是
Tips 3:
- redis应用于各种结构型和非结构型高热度数据访问加速
3. 数据库中热点数据key命名规范

4. string类型注意事项
数据操作不成功的反馈与数据正常操作之间的差异
- 表示运行结果是否成功:(integer)0–>false 失败、(integer)1–>true 成功
- 表示运行结果值:(integer)3、(integer)1
- 数据未获取到:(nil)等同于null
数据最大存储量:512MB 数值计算最大范围:java中的long的最大值,9223372036854775807
常用命令小结
SET key value #设定指定key的值
GET key #获取指定key的值
GETRANGE key start end #返回字符串的子串
SETRANGE key offset value #用value覆盖字符串的值,从offset开始
MGET/MSET key1 [value1] key2 [value2] #获取设置多个给定的key值
GETSET key value #将给定key的值设为value ,并返回key的旧值(old value)。
SETEX 将值 value #关联到 key,并设置 key 的过期时间为 seconds (以秒为单位)。
INCR/INCRBY key [num] #对value值加1/加num,value必须是数字
三、hash

我们用这种json的方式存储数据,查看数据很方便,修改数据较麻烦

第二种方式修改起来很方便,查看又不方便了

我们使用第三种hash的方式存储,这就能做到了,现在一个key对应一个hash类型的数据,我们把value理解为一个字典即可
map<key, map<key1, value>>
1. hash类型介绍
- 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息
- 需要的内存结构:一个存储空间保存多少个键值对数据
- hash类型:底层使用哈希表结构实现数据存储

2. hash类型基本操作
添加/修改数据
hset key field value

获取数据
hget key field
hgetall key

删除数据
hdel key field1 [field2]

添加/修改多个数据
hmset key field1 value1 field2 value2
获取多个数据
hmget key field1 field2 …

获取哈希表中field的数量
hlen key

获取哈希表中是否存在指定的字段
hexists key field

3. hash类型扩展操作
获取哈希表中所有的字段名和字段值
hkeys key # 获取key对应的hash数据类型中所有field
hvals key # 获取key对应的hash数据类型中所有value

设置指定字段的数值数据增加指定范围的值
hincrby key field increment
hincrbyfloat key field increment

4. hash类型数据操作的注意事项
hash类型下的value只能存储,不允许存储其他类型数据,不存在嵌套现象。如果数据未获取到,对应的值为**(nil)**
每个hash类型可以存储**个键值对**
hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,
hgetall操作可以获取key对应哈希类型所有的field以及value,,所以一般建议,
5. hash类型实际应用场景
购物车场景一

电商购物车中,将用户的id作为key;商品id作为field;数量作为value;hget可以获取value;hincrby增加value;hset设置value;删除商品就是删除一个field,可以使用hdel;全选所有商品,即获取所有的field,可以使用hgetall;商品数量即field的个数,可以使用hlen
127.0.0.1:6379> hmset user1 g01 100 g02 200 # user1在购物车添加100个g01商品,200个g02商品
OK
127.0.0.1:6379> hmset user2 g02 1 g04 7 g05 100 # user2在购物车添加1个g02商品,7个g04商品,100个g05商品
OK
127.0.0.1:6379> hset user1 g03 5 # user1在购物车中添加5个g03
(integer) 1
127.0.0.1:6379> hgetall user1 # 查看user1的购物车
1) "g01"
2) "100"
3) "g02"
4) "200"
5) "g03"
6) "5"
127.0.0.1:6379> hdel user1 g01 # user1删除购物车的g01商品
(integer) 1
127.0.0.1:6379> hgetall user1 # 查看user1的购物车
1) "g02"
2) "200"
3) "g03"
4) "5"
127.0.0.1:6379> hincrby user1 g03 1 # user1在购物车增加1个g03商品
(integer) 6
127.0.0.1:6379> hgetall user1 # 查看user1的购物车
1) "g02"
2) "200"
3) "g03"
4) "6"
127.0.0.1:6379>
当前设计是否加速了购物车的呈现?
我们用如下方式解决,


这个方法也是有

那每次买东西都添加商品信息,这不也会重复吗?我们使用hsetnx,已经添加过的商品(field)就不会再添加,相当于hexists + hset
- hsetnx :key对应的hash类型中,
- hset:key对应的hash类型中,
hsetnx key field value

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

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

string存储对象(json)与hash存储对象的区别:string存储对象讲究整体性,要么一次性更新,要么一次性获取,以读为主;
常用命令小结
HSET key field value #将哈希表 key 中的字段 field 的值设为 value
HMSET key field1 value1 [field2 value2 …] #同时将多个 field-value (域-值)对设置到哈希表 key 中
HGET key field / HMGET key field1 [field2] #获取给定字段的值
HGETALL key 获取在哈希表中指定 key 的所有字段和值
HKEYS key #获取所有哈希表中的字段
HVALS key #获取哈希表中所有值
HLEN key #获取哈希表中字段的数量