Redis五大数据类型(二)

二、五大数据类型

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理
它支持字符串、哈希表、列表、集合、有序集合位图,hyperloglogs等数据类型。
内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,
同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。

String(字符串)

追加

append key value 向指定的key的value后追加字符串
127.0.0.1:6379> set msg hello
OK
127.0.0.1:6379> append msg " world"
(integer) 11
127.0.0.1:6379> get msg
“hello world”

增加减少

decr/incr key 将指定key的value数值进行+1/-1(仅对于数字)
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> incr age
(integer) 21
127.0.0.1:6379> decr age
(integer) 20

incrby/decrby key n 按指定的步长对数值进行加减
127.0.0.1:6379> set age 20
127.0.0.1:6379> INCRBY age 5
(integer) 25
127.0.0.1:6379> DECRBY age 10
(integer) 15

INCRBYFLOAT key n 为数值加上浮点型数值
127.0.0.1:6379> INCRBYFLOAT age 5.2
“20.2”

字符串范围(闭区间)

strlen key 获取key保存值的字符串长度 127.0.0.1:6379> get msg “hello world” 127.0.0.1:6379> STRLEN msg (integer) 11

getrange key start end 按起止位置获取字符串(闭区间,起止位置都取)
127.0.0.1:6379> set name hhello
127.0.0.1:6379> getrange name 0 -1
"hhello"

替换指定位置字符串

setrange key offset value 用指定的value 替换key中 offset开始的值(包含offset)
127.0.0.1:6379> get name
"helloo"
127.0.0.1:6379> setrange name 1 xxx
(integer) 6
127.0.0.1:6379> get name
"hxxxoo"
127.0.0.1:6379>

*分布式锁中常用(set with expire与set if no exist)

setex key seconds value set 键值对 并 设置过期时间
设置name--“jack”且30秒后删除
127.0.0.1:6379> setex name 30 "jack"
OK
127.0.0.1:6379> get name
"jack"
127.0.0.1:6379> ttl name
(integer) 13
127.0.0.1:6379> get name
(nil)

setnx key value 仅当key不存在时进行set
127.0.0.1:6379> setnx name "11"
(integer) 1
127.0.0.1:6379> get name
"11"
127.0.0.1:6379> setnx name "dd"
(integer) 0

批量设置mset、mget

mset key1 value1 [key2 value2..] 批量set键值对
127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3

mget key1 value1 [key2 value2..] 批量获取多个key保存的值
127.0.0.1:6379> MGET k1 k2 k3

msetnx是一个原子性的操作,要么都成功,要么都失败

msetnx key1 value1 [key2 value2..] 批量设置键值对,仅当参数中所有的key都不存在时执行
127.0.0.1:6379> MSETNX k1 v1 k4 v4
(integer) 0

对象

127.0.0.1:6379> mset user:1:name jack user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age

  1. "jack"
  2. "2"

组合命令getset

getset key value 先get再set
如果不存在,返回nil;如果存在,将给定 key 的值设为 value ,并返回 key 的旧值(old value)
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mysql
"redis"
127.0.0.1:6379> get db
"mysql"

总结:String类似的使用场景

value除了是字符串还可以是数字,用途举例:

  • 计数器、粉丝数、对象存储缓存

  • 统计多单位的数量:uid:123666:follow 0

List(列表)

list列表,可以经过规则定义将其变为队列、栈、双端队列等。所有的list命令都是L开头

lpush/rpush key value1[value2..] 从左边/右边向列表中PUSH值(一个或者多个)。

lrange key start end 获取list 起止元素(索引从左往右 递增)

127.0.0.1:6379> lpush list a
(integer) 1
127.0.0.1:6379> lpush list b
(integer) 2
127.0.0.1:6379> rpush list c
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "b"   2) "a"   3) "c"

lpop/rpop key 从最左边/最右边移除值 并返回

lindex key index 通过索引获取列表元素

Llen key 查看列表长度

Lrem key count value 移除指定的,cout表示移除的个数,可省略

List中是允许value重复的
count > 0:从头部开始搜索 然后删除指定的value 至多删除count个
count < 0:从尾部开始搜索…
count = 0:删除列表中所有的指定value。

127.0.0.1:6379> lrange list 0 -1
1) "a"
2) "c"
127.0.0.1:6379> lrem list 1 a
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "c"

ltrim key start stop 修剪,截头截尾(key的下标从0开始,闭区间)

127.0.0.1:6379> lrange list 0 -1
"a" "b" "c" "d" "e"
127.0.0.1:6379> ltrim list 1 3
OK
127.0.0.1:6379> lrange list 0 -1
"b" "c" "d"

rpoplpush source destination 将列表的尾部(右)最后一个值弹出,并返回,然后添加到另一个列表的头部

127.0.0.1:6379> lrange list 0 -1
"b" "c" "d"
127.0.0.1:6379> rpoplpush list newlist
"d"
127.0.0.1:6379> lrange list 0 -1
"b" "c"
127.0.0.1:6379> lrange newlist 0 -1
"d"

lset key index value 通过索引为元素设值

127.0.0.1:6379> lrange list 0 -1
1) "old"
127.0.0.1:6379> lset list 0 new
OK
127.0.0.1:6379> lrange list 0 -1
1) "new"

linsert key BEFORE|AFTER pivot value 在指定列表元素的前/后 插入value

127.0.0.1:6379> lrange list 0 -1
 "a"
127.0.0.1:6379> linsert list before "a" "z"
127.0.0.1:6379> linsert list after "a" "b"
127.0.0.1:6379> lrange list 0 -1
 "z" "a" "b"

总结

list实际是一个链表,before, after , left, right 都可以插入值

如果移除了所有值,空链表,也代表不存在

在两边插入或者改动值,效率最高!修改中间元素,效率相对较低

应用:消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)

Set(无序集合)

Redis的Set是string类型的无序集合。集合成员是唯一的,
这就意味着集合中不能出现重复的数据

Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

命令

sadd key member1[member2..] 向集合中无序增加一个/多个成员

smembers key 返回集合中所有的成员

sismember key member1 查询member1元素是否是集合的成员,结果是无序的

scard key 获取集合的成员数

srem key member1[member2..] 移除集合中一个/多个成员

srandmember key [count] 随机返回集合中count个成员,count缺省值为1

spop key [count] 随机移除并返回集合中count个成员,count缺省值为1

smove source destination member 将source集合的成员member移动到destination集合

sdiff key1 [key2..] 返回所有集合的差集 key1- key2 - …
sinter key1 [key2..] 返回所有集合的交集
sunion key1 [key2..] 返回所有集合的并集

sdiffstore destination key1[key2..] 在SDIFF的基础上,将结果保存到集合中(覆盖)。不能保存到其他类型key噢!
sinterstore destination key1[key2..] 在SINTER的基础上,存储结果到集合中。覆盖
sunionstore destination key1 [key2..] 在SUNION的基础上,存储结果到集合中。覆盖

sscan key [MATCH pattern] [COUNT count] 在大量数据环境下,使用此命令遍历集合中元素,每次遍历部分??????

Hash(哈希)

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象

Set就是一种简化的Hash,只变动key,而value使用默认值填充。可以将一个Hash表作为一个对象进行存储,表中存放对象的信息。

命令

hset key field value 将哈希表 key 中的字段 field 的值设为 value 。重复设置同一个field会覆盖,返回0
hmset key field1 value1 [field2 value2..] 同时将多个 field-value (域-值)对设置到哈希表 key 中。
hget key field value 获取存储在哈希表中指定字段的值
hmget key field1 [field2..] 获取所有给定字段的值
hgetall key 获取在哈希表key 的所有字段和值

127.0.0.1:6379> hset myhash field1 "a"
(integer) 1
127.0.0.1:6379> hget myhash field1
"a"
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "a"

hdel key field1 [field2..] 删除哈希表key中一个/多个field字段

hsetnx key field value 只有在字段 field 不存在时,设置哈希表字段的值。
hexists key field 查看哈希表 key 中,指定的字段是否存在
hlen key 获取哈希表中字段的数量

hkeys key 获取哈希表key中所有的字段
hvals key 获取哈希表中所有

hincrby key field n 为哈希表 key 中的指定字段的整数值加上增量n,并返回增量后结果 一样只适用于整数型字段

HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对。

总结

Hash变更的数据user name age,尤其是用户信息之类的,经常变动的信息Hash更适合于对象的存储,Sring更加适合字符串存储!

Zset(有序集合)

sadd sset one 对比zadd sset 1 one,与set相比多了一个score

不同的是每个元素都会关联一个(double类型的) score
redis正是通过分数来为集合中的成员进行从小到大的排序。

score相同:按字典顺序排序

有序集合的成员是唯一的,但score却可以重复。

序集合的成员是唯一的,但分数(score)却可以重复。

命令

zadd key score member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
zrange key start end 通过索引区间返回有序集合成指定区间内的成员
zrevrange key start end 返回有序集中指定区间内的成员,通过索引,分数从高到底

127.0.0.1:6379> zadd sset 1 one
(integer) 1
127.0.0.1:6379> zadd sset 3 three 2 two
(integer) 2
127.0.0.1:6379> zrange sset 0 -1
1) "one"
2) "two"
3) "three"

zrem key member1 [member2..] 移除有序集合中一个/多个成员

zcard key 获取有序集合的成员数
zcount key min max 计算在有序集合中指定区间score的成员数
zincrby key n member 有序集合中对指定成员的分数加上增量 n
zscore key member 返回有序集中,成员的分数值
zrank key member 返回有序集合中指定成员的索引

zrangebylex key min max 通过字典区间返回有序集合的成员

zrangebyscore key min max 通过分数返回有序集合指定区间内的成员,其中-inf 和 +inf分别表示最小最大值,只支持开区间()

应用案例

set排序、 存储班级成绩表、 工资表排序

带权重进行判断:普通消息--1. 重要消息--2.

排行榜应用实现,取Top N测试

三、三种特殊数据类型

1 Geospatial(地理位置)

使用经纬度定位地理坐标并用一个有序集合zset保存,所以zset命令也可以使用

geoadd key longitud(经度) latitude(纬度) member(城市名) [..] 将具体经纬度的坐标存入一个有序集合
geopos key member [member..] 获取集合中的一个/多个成员坐标
geopos china:city beijing

geodist key member1 member2 [unit] 返回两个给定位置之间的距离。默认以米作为单位。
(unit:m 表示单位为米。 km 表示单位为千米)
查看北京到上海的直线距离:geodist china:city beijing shanghai km

georadius key longitude latitude radius km [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
以给定的经纬度为中心, 找出某一半径内的元素
radius:半径;withcoord:带上坐标;withdist:带上距离,单位与半径单位相同;COUNT n:只显示前n个(按距离递增排序)
georadiusbymember key member radius... 功能与georadius相同,只是中心位置不是具体的经纬度,而是使用结合中已有的成员作为中心点

geohash key member1 [member2..] 返回一个或多个位置元素的Geohash表示。使用Geohash位置52点整数编码。

移除元素:由于geo底层是zset,可以使用:
zrem china:city beijing

2 Hyperloglog(基数统计)

简介

Redis HyperLogLog 是用来做基数(数据集中不重复的元素的个数)统计的算法
HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。其底层使用string数据类型

应用场景

网页的访问量(UV):一个用户多次访问,也只能算作一个人。

传统实现:存储用户的id,然后每次进行比较。当用户变多之后这种方式及其浪费空间,而我们的目的只是计数,Hyperloglog就能帮助我们利用最小的空间完成。

如果允许容错,那么一定可以使用Hyperloglog !
如果不允许容错,就使用set或者自己的数据类型即可 !

命令

PFadd key element1 [elememt2..] 添加指定元素到 HyperLogLog 中
PFcount key [key] 返回给定 HyperLogLog 的基数估算值。

PFmerge destkey sourcekey [sourcekey..] 将多个 HyperLogLog 合并为一个 HyperLogLog
合并myelemx和myelemy 成为myelemz :PFmerge myelemz myelemx myelemy

127.0.0.1:6379> pfadd key a b c d e 
(integer) 1
127.0.0.1:6379> pfadd key1 a b c r g g
(integer) 1
127.0.0.1:6379> pfmerge key2 key key1
OK
127.0.0.1:6379> pfcount key2
(integer) 7  #合并后只有7个了 ,abcde+rg

3 BitMaps(位图)

使用位存储,信息状态只有 0 和 1

Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR,NOT以及其它位操作。

应用场景:签到统计、状态统计

setbit、getbit、bitcount
bitcount key [start end] 统计字符串被设置为1的bit数,也可以指定统计范围按字节

------------setbit--getbit--------------
127.0.0.1:6379> setbit sign 0 1 # 设置sign的第0位为 1 
(integer) 0
127.0.0.1:6379> setbit sign 2 1 # 设置sign的第2位为 1  不设置默认 是0
(integer) 0
127.0.0.1:6379> setbit sign 3 0

127.0.0.1:6379> getbit sign 2 # 获取第2位的数值
(integer) 1

-----------bitcount----------------------------
127.0.0.1:6379> bitcount sign  # 统计sign中为1的位数
(integer) 2

https://www.bilibili.com/video/BV1S54y1R7SB?from=search&seid=3929831479981400108

posted @ 2022-04-02 08:44  yu10001  阅读(57)  评论(0编辑  收藏  举报