一、String数据类型
1、作为缓存使用
- 原始业务功能设计
- 秒杀
- 618活动
- 双11活动
- 排队购票
- 运营平台监控到的突发高频访问数据
- 突发时政要闻,被强势关注围观
高频,复杂的统计数据
系统功能优化或升级
string 【字符串】
- hash 【HashMap】
- list 【链表】
- set 【hashset】
- sorted_set 【treeSet】
4、Redis数据存储格式
- 存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型
- 存储数据的格式:一个存储空间保存一个数据
- 存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用
6、string 类型数据的基础操作
- 添加/修改数据
set key value
- 获取数据
get key
- 删除数据 (操作 如果成功:返回 integer 1 ,失败返回 :integer 0)
del key
- 添加/修改多个数据
mset key1 value1 key2 value2 ..
- 获取多个数据
mget key1 key2
- 获取数据字符个数(字符串长度)
strlen key
- 追加到原始信息后部(如果存在就追加,如果不存在就新建)
append key value
- 大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键 id 必须保证统一性 ,不能重复。Oracle 数据库具有 sequence 设定,可以解决该问题,但是 MySQL数据库并不具有类似的机 制,那么如何解决?
解决方案:
- 设置数值数据增加指定范围的值
- incr key ** **[如果key 是1 ,那么会增1]
- incrby key **步长** [如果key是1 步长是2 那么会 1+2]
- incrbyfloat key **小数步长** [如果key 是1 步长是 0.5 那么会 1+0.5]
- 设置数值数据减少指定范围的值
- decr key ** **[如果key 是1 ,那么会减1]
- decrby key **步长** [如果key是1 步长是2 那么会 1-2]
- string作为数值操作
- string在redis内部存储默认就是一个字符串,当遇到增减类操作 incr decr 时会转换成数值型进行计算
- redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响
- 注意:按照数值进行操作的数据,如果原始数据不能转成数据,或超越了redis数值上线范围,将报错:9223372036854775807(java中long型数据最大值,Long.MAX_VALUE)
问题:
- “最强女生”启动海选投票,只能通过微信投票,每个微信号每 4 小时只能投1票。
- 电商商家开启热门商品推荐,热门商品不能一直处于热门期,每种商品热门期维持3天,3天后自动取消热门。
- 新闻网站会出现热点新闻,热点新闻最大的特征是时效性,如何自动控制热点新闻的时效性
解决方案:
- 设置数据具有指定的声明周期
- setex key **秒** value [设置这个key value 能存在几秒]
- psetex key **毫秒** value [同上]
- redis控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作
8、string类型操作注意事项
数据操作不成功的反馈和数据正操操作之间的差异
- 表示运行结果是否成功
- (integer)0 表示false 失败
- (integer)1 表示true 成功
- 表示运行结果值
- (integer)1 表示结果值1个
- (integer)2 表示结果值2个
- 数据为查询到
- nil
- 数据最大存储量
- 512MB
- 数值计算最大范围(java中long的最大值)
- 9223372036854775807
9、string类型应用场景
业务场景:主页高频访问信息显示控制,例如微博大V的粉丝数量
解决方案:
- 在redis中为大V设定用户信息,以用户主键和属性值作为key,后台设定定时刷新策略即可
- eg: user:id:3506728370:fans → 12210947
- eg: user:id:3506728370:blogs → 6164
- eg: user:id:3506728370:focuss → 83
user 表名,id用户主键,350..主键值,fans属性值 使用冒号区分
- 在redis中使用json格式存储大V用户信息,定时刷新
- user:id:3506728370 -> {“id”:3506728370,”name”:”春晚”,”fans”:12210862,”blogs”:6164, “focus”:83}
- key 是 user:id:350.. value是 json
- redis应用于各种结构性和非结构性高热度数据访问加速
10、Key的设置约定
数据库中的热点数据 key命令惯例
- 表名:主键名:主键值:字段名
- 例如:key:user:id:330:name
二、Hash数据类型
1、存储的困惑
- 对象类数据的存储如果具有较为频繁的更新需求操作会显得十分笨重
- 例如:key: user:id:3330 value:{name:春晚,fans:1222000,blogs:6461,focus:83}
- 如果改为 这样也不是很好
- user:id:3330:name -> 春晚
- user:id:3330:fans -> 1222000
- user:id:3330:blogs -> 6461
2、Hash类型
- 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息
- 需要的存储结构:一个存储空间保存多个键值对数据
-
3、Hash存储结构优化
如果field数量较少,存储结构优化为类数组[类似数组]结构
- 如果field数量较多,存储结构使用HashMap结构
4、Hash基本操作
- 添加/修改数据
- hset key field value
- 获取数据
- hget key field
- hgetall key [获取所有的 field和value]
- 删除数据
- hdel key field1
- 删除/修改多个数据
- hmset key field1 value1 field2 value2
- 获取多个数据
- hmget key field1 field2
- 获取哈希表中字段的数量
- hlen key
获取哈希表中是否存在指定的字段
获取哈希表中所有的字段名或字段值
- hkeys key
- hvals key
设置指定字段的数值数据增加指定范围的值
Hash类型下的value只能存储字符串,不允许储存其他数据类型,不存在嵌套现象,如果数据未获取到,对应的值为 nil。
- 每个 hash可以存储 232 - 1 个键值对。
- hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象树形,但是hash设计初衷不是为了存储大量对象而设计的,切记不可滥用,更不可以将hash作为对象列表使用。
hgetall 可以获取 hash里面的所有的 field 和value ,但是如果内部field过多,遍历整体数据就很低,有可能成为数据访问瓶颈。
7、Hash类型应用场景
业务场景:
- 电商网站购物车设计与实现
用户id作为key 产品id:field 数量:value
- hsetnx key field value
- 如果当前key中的 field有值 就什么都不做,如果没有值就加入进去
- 设置成功,返回1。如果给定字段已经存在且没有操作被执行,返回 0 。
- string存储对象(Json) 和hash存储对象的区别
- string 用JSON格式存对象讲究整体性,讲究以读为主
- hash 讲究以改为主【常改用hash 只是用来读用string】
三、List数据类型
- 数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
- 需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序
- list类型:保存多个数据,底层使用双向链表存储结构实现
- list索引从0开始
1、List类型数据基本操作
- 添加/修改数据
- lpush key value1 [value2] [value3] [从左边进]
- rpush key value1 [value2] [value3] [从右边进]
- 获取数据
- lrange key start stop
- lrange key 0 -1 可以查看列表中所有的数据
- lindex key index
- llen key
- lrange key start stop
- 获取并移除数据
- lpop key 从左边弹出数据
- rpop key 从右边弹出数据
注意:从左边进入的数据 a b c,出来的时候是 c b a,因为从左进入一个一个往后推
2、list类型数据拓展操作
- 规定时间内获取并移除数据
- blpop key1 [key2] timeout
- brpop key1 [key2] timeout
- 注意:如果 list里面没有 那么就会等,如果一有了以后直接弹出来【用两个客户端可以模拟】
- timeout 单位为 秒
- 从中间删除一个元素
- 微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息
企业运营过程中,系统将产生出大量的运营数据,如何保障多台服务器操作日志的统一顺序输出?
list中保存的数据都是string类型的,数据总容量是有限的,最多 2的32次方 -1个元素
- list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以站的执行进行入栈出栈操作
- 获取全部数据操作结束索引设置为 -1
- list可以对数据进行分页操作,通常第一页的信息来自list,第二页以及更多的信息通过数据库的加载形式加载
四、Set数据类型
- 新的存储需求:存储大量的数据,在查询方面提供更高的效率
- 需要的存储结构:能够保存大量的数据,搞笑的内存存储机制,便于查询
- set类型:与hash存储结构完全相同,仅存储键,不存储值(nil) 并且键是不允许为重复的
1、set类型数据的基本操作
- 添加数据
- sadd key member1 [member2]
- 获取全部数据
- smembers key
- 删除数据
- srem key member1 [member2]
- 获取集合数据总量
- scard key
- 判断集合中是否包含该数据
- sismember key member
2、set类型数据的拓展操作
- 随机获取集合中指定数据量的数据
- srandmember key [count]
- 随机获取集合中的某个数据并将数据移出集合
- spop key
- 求两个集合的交、并、差集
- sinter key1 [key2]
- sunion key1 [key2]
- sdiff key1 [key2]
- 求两个集合的交、并、差集并存储到指定集合中
- sinterstore destination key1 [key2]
- sunionstore destination key1 [key2]
- sdiffstore destination key1 [key2]
- 将指定数据从原始集合中移动到目标集合中
- smove source destination member
- redis 应用于同类信息的关联搜索,二度关联搜索,深度关联搜索
- 显示共同关注(一度)
- 显示共同好友(一度)
- 由用户A出发,获取到好友用户B的好友信息列表(一度)
- 由用户A出发,获取到好友用户B的购物清单列表(二度)
-
3、set注意事项
set类型不允许数据重复,如果添加的数据在set中已经存在了,将只保留一份
- set虽然和hash的存储结构相同,但是无法启用hash中存储值的空间
- redis 应用于基于黑名单与白名单设定的服务控制
五、Sorted_set 数据类型
- 新的存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征及逆行排序的方式
- 需要的存储结构:新的存储模型,可以保存可排序的数据
- sorted_set: 在set的存储结构基础上添加可排序字段
1、基础操作
- 添加数据
zadd key score1 member1 [score2 member2]
- 获取全部数据
zrange key start stop [withscores] 【从小到大】
zrevrangekey start stop [withscores] 【从大到小】
- 删除数据
- zrem key member [member]
- 按条件获取数据
- zrangebyscore key min max [withscores] [limit]
- zrevrangebyscore key max min [withscores]
- 条件删除数据
- zremrangebyrank key start top 【按照索引删除】
- zremrangebyscore key min max 【按照 score 删除】
注意:
- min与max用于限定搜索查询的条件
- start 与 stop 用于限定查询范围,用于索引,表示开始和结束索引
- offset与count用于限定查询方位,作用于查询结果,表示开位置和数据总量
获取数据总量
- zcard key
- zcount key min max
集合交,并操作
- zinterstroe destination numkeys key [key …]
- zunionstore destination numkeys key [key …]
2、sorted_set 拓展操作
- 获取数据对应的索引(排名) 索引从0开始
- zrank key member 【从小到大 是第几个索引】
- zrevrank key member 【从大到小 是第几个索引】
score 值获取与修改
score保存的数据存储空间是64位,范围是java中long的范围
- score保存的数据也可以是一个双精度的double值,但是基于双精度浮点数的特征,可能会丢失精度,使用时慎重
- sorted_set 底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被覆盖,保留最后一次的修改结果 【set 如果相同 会操作失败】