Redis 数据类型
string String
hash HashMap
list LinkedList
set HashSet
sorted_set TreeSet
redis 数据存储格式
redis 自身是一个 Map,其中所有的数据都是采用 key : value 的形式存储
数据类型指的是存储的数据的类型,也就是 value 部分的类型,key 部分永远都是字符串

string 类型

string 操作
存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型存储数据的格式:一个存储空间保存一个数据存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用添加/修改数据set key value获取数据get key删除数据del key127.0.0.1:6379> set age 100OK127.0.0.1:6379> get age"100"127.0.0.1:6379> del age(integer) 1127.0.0.1:6379> del age(integer) 0添加/修改多个数据mset key1 value1 key2 value2 …获取多个数据mget key1 key2 …获取数据字符个数(字符串长度)strlen key追加信息到原始信息后部(如果原始信息存在就追加,否则新建)append key value127.0.0.1:6379> mset set a 1 b 2 c 3(error) ERR wrong number of arguments for MSET127.0.0.1:6379> mset a 1 b 2 c 3OK127.0.0.1:6379> mget a b c1) "1"2) "2"3) "3"127.0.0.1:6379> strlen a(integer) 1127.0.0.1:6379> append a 23(integer) 3127.0.0.1:6379> get a"123"设置数值数据增加指定范围的值incr key # 增加1incrby key incrementincrbyfloat key increment127.0.0.1:6379> get a"123"127.0.0.1:6379> incr a(integer) 124127.0.0.1:6379> incrby a 26(integer) 150127.0.0.1:6379> incrbyfloat a 50"200"设置数值数据减少指定范围的值decr key # 减少1decrby key increment127.0.0.1:6379> get a"174"127.0.0.1:6379> decr a(integer) 173127.0.0.1:6379> decrby a 25(integer) 148string 作为数值操作string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算。redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响。注意:按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis 数值上限范围,将报错。9223372036854775807(java中long型数据最大值,Long.MAX_VALUE)Tips 1:redis用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性此方案适用于所有数据库,且支持数据库集群设置数据具有指定的生命周期setex key seconds value # 秒为单位psetex key milliseconds value # 毫秒为单位Tips 2:redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作127.0.0.1:6379> setex a 5 1OK127.0.0.1:6379> get a"1"127.0.0.1:6379> get a(nil)127.0.0.1:6379> psetex a 5000 2OK127.0.0.1:6379> get a"2"127.0.0.1:6379> get a"2"127.0.0.1:6379> get a(nil)string 类型数据操作的注意事项数据操作不成功的反馈与数据正常操作之间的差异① 表示运行结果是否成功(integer) 0 → false 失败(integer) 1 → true 成功② 表示运行结果值(integer) 3 → 3 3个(integer) 1 → 1 1个数据未获取到(nil)等同于null数据最大存储量512MB数值计算最大范围(java中的long的最大值)9223372036854775807
string 类型应用场景

在redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定定时刷新策略即可eg: user:id:3506728370:fans → 12210947eg: user:id:3506728370:blogs → 6164eg: user:id:3506728370:focuss → 83127.0.0.1:6379> set user:id:3506728370:fans 12210947OK127.0.0.1:6379> get user:id:3506728370:fans"12210947"127.0.0.1:6379> set user:id:3506728370:blogs 6164OKget user:id:3506728370:blogs"6164"127.0.0.1:6379> set user:id:3506728370:focuss 83OK127.0.0.1:6379> get user:id:3506728370:focuss"83"在redis中以json格式存储大V用户信息,定时刷新(也可以使用hash类型)eg: user:id:3506728370 →{"id":3506728370,"name":"春晚","fans":12210862,"blogs":6164, "focus":83}Tips 3:redis应用于各种结构型和非结构型高热度数据访问加速
hash
hash操作
添加/修改数据hset key field value获取数据hget key fieldhgetall key删除数据hdel key field1 [field2]127.0.0.1:6379> hset a name xiaoming(integer) 1127.0.0.1:6379> hset a age 18(integer) 1127.0.0.1:6379> hget a name"xiaoming"127.0.0.1:6379> hgetall a1) "name"2) "xiaoming"3) "age"4) "18"127.0.0.1:6379> hdel a name(integer) 1127.0.0.1:6379> hgetall a1) "age"2) "18"添加/修改多个数据hmset key field1 valuel field2 value2获取多个数据hmget key fieldl field2获取哈希表中字段的数量hlen key获取哈希表中是否存在指定的字段exists key field127.0.0.1:6379> hmset a name xiaohong age 20OK127.0.0.1:6379> hmget a name age1) "xiaohong"2) "20"127.0.0.1:6379> hlen a(integer) 2127.0.0.1:6379> exists a name(integer) 1获取哈希表中所有的字段名或字段值keys keyhals key127.0.0.1:6379> hkeys a1) "age"2) "name"127.0.0.1:6379> hvals a1) "20"2) "xiaohong"设置指定字段的数值数据増加指定范围的值hincrby key field incrementhincrbyfloat key field increment127.0.0.1:6379> hincrby a age 10(integer) 30127.0.0.1:6379> hgetall a1) "age"2) "30"3) "name"4) "xiaohong"127.0.0.1:6379> hincrbyfloat a age 30.1"60.1"127.0.0.1:6379> hgetall a1) "age"2) "60.1"3) "name"4) "xiaohong"hash类型数据操作的注意事项hash类型下的 value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到,对应的值为(nil)每个hash可以存储2^32-1个键值对hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,切记不可滥用,更不可以将hash作为对象列表使用hgetal操作可以获取全部属性,如果内部 field过多,遍历整体数据效率就会很低,有可能成为数据访问瓶颈
Hash 类型应用场景
电商网站购物车设计与实现

解决方案以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息将商品编号作为field,购买数量作为value进行存储添加商品:追加全新的field与value浏览:遍历hash更改数量:自增/自减,设置value值删除商品:删除field清空:删除key此处仅讨论购物车中的模型设计购物车与数据库间持久化同步、购物车与订单间关系、未登录用户购物车信息存储不进行讨论127.0.0.1:6379> hmset 001 g01 100 g02 200OK127.0.0.1:6379> hmset 002 g02 1 g04 7 g05 100OK127.0.0.1:6379> hset 001 g03 5(integer) 1127.0.0.1:6379> hgetall 0011) "g01"2) "100"3) "g02"4) "200"5) "g03"6) "5"127.0.0.1:6379> hdel 001 g01(integer) 1127.0.0.1:6379> hgetall 0011) "g02"2) "200"3) "g03"4) "5"127.0.0.1:6379> hincrby 001 g03 1(integer) 6127.0.0.1:6379> hgetall 0011) "g02"2) "200"3) "g03"4) "6"
list
list操作
数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序list类型:保存多个数据,底层使用双向链表存储结构实现添加/修改数据lpush key value1 [value2] ……rpush key value1 [value2] ……获取数据lrange key start stoplindex key indexllen key获取并移除数据lpop keyrpop key127.0.0.1:6379> lpush list1 a b c(integer) 3127.0.0.1:6379> rpush list2 d e f(integer) 3127.0.0.1:6379> lrange list1 0 -11) "c"2) "b"3) "a"127.0.0.1:6379> lrange list2 0 -11) "d"2) "e"3) "f"127.0.0.1:6379> lindex list1 0"c"127.0.0.1:6379> lindex list1 -1"a"127.0.0.1:6379> lindex list1 -2"b"127.0.0.1:6379> llen list1(integer) 3127.0.0.1:6379> llen list2(integer) 3127.0.0.1:6379> lpop list1"c"127.0.0.1:6379> rpop list1"a"127.0.0.1:6379> llen list1(integer) 1127.0.0.1:6379> lpop list2"d"127.0.0.1:6379> rpop list2"f"127.0.0.1:6379> llen list2(integer) 1规定时间内获取并移除数据blpop key1 [key2] timeoutbrpop key1 [key2] timeout127.0.0.1:6379> keys *1) "list2"127.0.0.1:6379> lpush list1 aa(integer) 1127.0.0.1:6379> keys *1) "list2"127.0.0.1:6379> lpush list3 bb(integer) 1127.0.0.1:6379>127.0.0.1:6379> blpop list1 101) "list1"2) "aa"127.0.0.1:6379> blpop list3 101) "list3"2) "bb"(3.78s)
List 类型应用场景

list 类型数据扩展操作移除指定数据lrem key count value # count表示移除的个数Tips 6:redis 应用于具有操作先后顺序的数据控制127.0.0.1:6379> lpush list1 a b c d a(integer) 5127.0.0.1:6379> lrange list1 0 -11) "a"2) "d"3) "c"4) "b"5) "a"127.0.0.1:6379> lrem list1 2 a(integer) 2127.0.0.1:6379> llen list1(integer) 3127.0.0.1:6379> lrange list1 0 -11) "d"2) "c"3) "b"
set类型
set操作
新的存储需求:存储大量的数据,在查询方面提供更高的效率需要的存储结构:能够保存大量的数据,高效的内部存储机制,便于查询set类型:与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的set 类型数据的基本操作添加数据sadd key member1 [member2]获取全部数据smembers key删除数据srem key member1 [member2]获取集合数据总量scard key判断集合中是否包含指定数据sismember key member127.0.0.1:6379> sadd users zs(integer) 1127.0.0.1:6379> sadd users ls(integer) 1127.0.0.1:6379> sadd users ww(integer) 1127.0.0.1:6379> smembers users1) "zs"2) "ww"3) "ls"127.0.0.1:6379> srem users ww(integer) 1127.0.0.1:6379> smembers users1) "zs"2) "ls"127.0.0.1:6379> scard users(integer) 2127.0.0.1:6379> sismember users zs(integer) 1127.0.0.1:6379> sismember users ww(integer) 0set 类型数据操作的注意事项set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间127.0.0.1:6379> sadd a a(integer) 1127.0.0.1:6379> sadd a a(integer) 0127.0.0.1:6379> hset a a 1(error) WRONGTYPE Operation against a key holding the wrong kind of valueset 类型数据的扩展操作随机获取集合中指定数量的数据srandmember key [count]随机获取集合中的某个数据并将该数据移出集合spop key [count]Tips 8:redis 应用于随机推荐类信息检索,例如热点歌单推荐,热点新闻推荐,热卖旅游线路,应用APP推荐,大V推荐等Tips 9:redis 应用于同类信息的关联搜索,二度关联搜索,深度关联搜索显示共同关注(一度)显示共同好友(一度)由用户A出发,获取到好友用户B的好友信息列表(一度)由用户A出发,获取到好友用户B的购物清单列表(二度)由用户A出发,获取到好友用户B的游戏充值列表(二度)127.0.0.1:6379> sadd news n1(integer) 1127.0.0.1:6379> sadd news n2(integer) 1127.0.0.1:6379> sadd news n3(integer) 1127.0.0.1:6379> sadd news n4(integer) 1127.0.0.1:6379> srandmember news 11) "n1"127.0.0.1:6379> srandmember news 11) "n1"127.0.0.1:6379> srandmember news 11) "n1"127.0.0.1:6379> srandmember news 11) "n3"127.0.0.1:6379> scard news(integer) 4127.0.0.1:6379> spop news 11) "n1"127.0.0.1:6379> smembers news1) "n4"2) "n2"3) "n3"127.0.0.1:6379> spop news 21) "n4"2) "n3"127.0.0.1:6379> smembers news1) "n2"求两个集合的交、并、差集sinter key1 [key2]sunion key1 [key2]sdiff key1 [key2]求两个集合的交、并、差集并存储到指定集合中sinterstore destination key1 [key2]sunionstore destination key1 [key2]sdiffstore destination key1 [key2]将指定数据从原始集合中移动到目标集合中smove source destination member127.0.0.1:6379> sadd u1 a1(integer) 1127.0.0.1:6379> sadd u1 s1(integer) 1127.0.0.1:6379> sadd u1 b1(integer) 1127.0.0.1:6379> sadd u2 s1(integer) 1127.0.0.1:6379> sadd u2 w1(integer) 1127.0.0.1:6379> sinter u1 u21) "s1"127.0.0.1:6379> sunion u1 u21) "a1"2) "s1"3) "w1"4) "b1"127.0.0.1:6379> sdiff u1 u21) "a1"2) "b1"127.0.0.1:6379> sdiff u2 u11) "w1"127.0.0.1:6379> sdiffstore u3 u1 u2(integer) 2127.0.0.1:6379> smembers u31) "a1"2) "b1"127.0.0.1:6379> smove u2 u1 w1(integer) 1127.0.0.1:6379> smembers u11) "a1"2) "s1"3) "w1"4) "b1"127.0.0.1:6379> smembers u21) "s1"
Set 类型应用场景
权限校验
集团公司共具有12000名员工,内部OA系统中具有700多个角色,3000多个业务操作,23000多种数据,每位员工具有一个或多个角色,可以快速进行业务操作的权限校验

127.0.0.1:6379> sadd rid:001 getall(integer) 1127.0.0.1:6379> sadd rid:001 getById(integer) 1127.0.0.1:6379> sadd rid:002 getall(integer) 1127.0.0.1:6379> sadd rid:002 getCount(integer) 1127.0.0.1:6379> sadd rid:002 insert(integer) 1127.0.0.1:6379> sunionstore uid:007 rid:001 rid:002(integer) 4127.0.0.1:6379> smembers uid:0071) "insert"2) "getById"3) "getCount"4) "getall"127.0.0.1:6379> sismember uid:007 insert(integer) 1
sorted_set
sorted_set操作
新的存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式
需要的存储结构:新的存储模型,可以保存可排序的数据
sorted_set类型:在set的存储结构基础上添加可排序字段
sorted_set 类型数据的基本操作添加数据zadd key score1 member1 [score2 member2]获取全部数据zrange key start stop [WITHSCORES]zrevrange key start stop [WITHSCORES]删除数据zrem key member [member ...]按条件获取数据zrangebyscore key min max [WITHSCORES] [LIMIT]zrevrangebyscore key max min [WITHSCORES]条件删除数据zremrangebyrank key start stopzremrangebyscore key min max注意:min与max用于限定搜索查询的条件start与stop用于限定查询范围,作用于索引,表示开始和结束索引offset与count用于限定查询范围,作用于查询结果,表示开始位置和数据总量获取集合数据总量zcard keyzcount key min max集合交、并操作zinterstore destination numkeys key [key ...]zunionstore destination numkeys key [key ...]127.0.0.1:6379> zadd scores 94 zs(integer) 1127.0.0.1:6379> zadd scores 100 ls(integer) 1127.0.0.1:6379> zadd scores 60 ww(integer) 1127.0.0.1:6379> zadd scores 47 zl(integer) 1127.0.0.1:6379> zrange scores 0 -11) "zl"2) "ww"3) "zs"4) "ls"127.0.0.1:6379> zrange scores 0 -1 withscores1) "zl"2) "47"3) "ww"4) "60"5) "zs"6) "94"7) "ls"8) "100"127.0.0.1:6379> zrevrange scores 0 -1 withscores1) "ls"2) "100"3) "zs"4) "94"5) "ww"6) "60"7) "zl"8) "47"127.0.0.1:6379> zrem scores ls(integer) 1127.0.0.1:6379> zrevrange scores 0 -1 withscores1) "zs"2) "94"3) "ww"4) "60"5) "zl"6) "47"127.0.0.1:6379> zrange scores 0 -1 withscores1) "wangwu"2) "45"3) "zhangsan"4) "67"5) "zhouqi"6) "71"7) "qianba"8) "92"9) "lisi"10) "99"11) "zhangliu"12) "100"127.0.0.1:6379> zrangebyscore scores 50 80 withscores1) "zhangsan"2) "67"3) "zhouqi"4) "71"127.0.0.1:6379> zrevrangebyscore scores 80 50 withscores1) "zhouqi"2) "71"3) "zhangsan"4) "67"127.0.0.1:6379> zrangebyscore scores 50 99 withscores1) "zhangsan"2) "67"3) "zhouqi"4) "71"5) "qianba"6) "92"7) "lisi"8) "99"127.0.0.1:6379> zrangebyscore scores 50 99 withscores limit 0 31) "zhangsan"2) "67"3) "zhouqi"4) "71"5) "qianba"6) "92"127.0.0.1:6379> zrangebyscore scores 50 99 withscores limit 0 11) "zhangsan"2) "67"127.0.0.1:6379> zremrangebyscore scores 50 70(integer) 1127.0.0.1:6379> zrange scores 0 -1 withscores1) "wangwu"2) "45"3) "zhouqi"4) "71"5) "qianba"6) "92"7) "lisi"8) "99"9) "zhangliu"10) "100"127.0.0.1:6379> zremrangebyrank scores 0 1(integer) 2127.0.0.1:6379> zrange scores 0 -1 withscores1) "qianba"2) "92"3) "lisi"4) "99"5) "zhangliu"6) "100"127.0.0.1:6379> zcard scores(integer) 3127.0.0.1:6379> zcount scores 99 200(integer) 2127.0.0.1:6379> zadd s1 50 aa 60 bb 70 cc(integer) 3127.0.0.1:6379> zadd s2 60 aa 40 bb 90 aa(integer) 2127.0.0.1:6379> zadd s3 70 aa 20 bb 100 dd(integer) 3127.0.0.1:6379> zinterstore sss 3 s1 s2 s3 # 求和(integer) 2127.0.0.1:6379> zrange sss 0 -1 withscores1) "bb"2) "120"3) "aa"4) "210"127.0.0.1:6379> zinterstore ssss 3 s1 s2 s3 aggregate max # 求最大值(integer) 2127.0.0.1:6379> zrange ssss 0 -1 withscores1) "bb"2) "60"3) "aa"4) "90"127.0.0.1:6379> help zunionstoreZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]summary: Add multiple sorted sets and store the resulting sorted set in a new keysince: 2.0.0group: sorted_set127.0.0.1:6379> help zinterstoreZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]summary: Intersect multiple sorted sets and store the resulting sorted set in a new keysince: 2.0.0group: sorted_setsorted_set 类型数据的扩展操作获取数据对应的索引(排名)zrank key memberzrevrank key memberscore值获取与修改zscore key memberzincrby key increment memberTips 11:redis 应用于计数器组合排序功能对应的排名127.0.0.1:6379> zadd movies 143 aa 97 bb 201 cc(integer) 3127.0.0.1:6379> zrank movies bb(integer) 0127.0.0.1:6379> zrevrank movies bb(integer) 2127.0.0.1:6379> zscore movies aa"143"127.0.0.1:6379> zincrby movies 1 aa"144"127.0.0.1:6379> zscore movies aa"144"sorted_set 类型数据操作的注意事项score保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992score保存的数据也可以是一个双精度的double值,基于双精度浮点数的特征,可能会丢失精度,使用时候要慎重sorted_set 底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被反复覆盖,保留最后一次修改的结果
sorted_set 类型应用场景
微信接受消息顺序控制
使用微信的过程中,当微信接收消息后,会默认将最近接收的消息置顶,当多个好友及关注的订阅号同时发送消息时,该排序会不停的进行交替。同时还可以将重要的会话设置为置顶。一旦用户离线后,再次打开微信时,消息该按照什么样的顺序显示?依赖list的数据具有顺序的特征对消息进行管理,将list结构作为栈使用对置顶与普通会话分别创建独立的list分别管理当某个list中接收到用户消息后,将消息发送方的id从list的一侧加入list(此处设定左侧)多个相同id发出的消息反复入栈会出现问题,在入栈之前无论是否具有当前id对应的消息,先删除对应id推送消息时先推送置顶会话list,再推送普通会话list,推送完成的list清除所有数据消息的数量,也就是微信用户对话数量采用计数器的思想另行记录,伴随list操作同步更新Tips 15:redis 应用于基于时间顺序的数据操作,而不关注具体时间

127.0.0.1:6379> lrem 100 1 200(integer) 0127.0.0.1:6379> lpush 100 200(integer) 1127.0.0.1:6379> lrem 100 1 300(integer) 0127.0.0.1:6379> lpush 100 300(integer) 2127.0.0.1:6379> lrem 100 1 400(integer) 0127.0.0.1:6379> lpush 100 400(integer) 3127.0.0.1:6379> lrem 100 1 200(integer) 1127.0.0.1:6379> lpush 100 200(integer) 3127.0.0.1:6379> lrem 100 1 300(integer) 1127.0.0.1:6379> lpush 100 300(integer) 3127.0.0.1:6379> lrange 100 0 -11) "300"2) "200"3) "400"
文章转载自猿视野,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





