redis 操作命令和数据类型
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件MQ。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。
Redis 内置了 复制(replication),LUA脚本(Luascripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
redis-key
keys * # 查看当前数据库下所有 key
set keyname keyvalue # 设置键值(String 类型)设置相同键值会产生覆盖
exists keyname # 判断键是否存在
type keyname # 判断键的数据类型 (默认情况下为 string 类型)
get keyname # 得到键的值
expire keyname 10 # 设置键的过期时间(短信验证码)
ttl keyname # 查看键的有效时间
clear # 清屏操作
![image-20200920104005582 image-20200920104005582](https://i-blog.csdnimg.cn/blog_migrate/3ca789325d0bb6c033e60166709a88f7.png)
String(字符串)
set keyname kayvalue # 设置值
get keyname # 获得值
keys * # 列出当前数据库中所有的 keyname
exists keyname # 判断一个 key 是否存在
append keyname "*" # 向一个 keyname 后追加字符串,如果当前 key不存在 就相当于setKey
strlen keyname # 获取字符串长度
incr keyname # 键值自增 1 ,键值必须为数值
decr keyname # 键值自减1 键值必须为数值
incrby keyname 10 # 设置增量步长
decrby keyname 10 # 设置减量步长
getrange keyname 0 3 # 截取0-3 索引位置字符串
getrange keyname 0 -1 # 相当于 get keyname
setrange keyname 1 xx # 从指定位置替换字符串
setex keyname 30 "***" # 设置字符串指定过期时间
setnx keyname "****" # 如果mykey不存在,创建 mykey,存在,创建失败,且不会发生值的替换
mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
mget k1 k2 k3 # 同时获取多个值
msetnx k1 v1 k4 v4 # msetnx 是一个原子性的操作,要么一起成功,要么一起 失败!
set user:1 {name:zhangsan,age:3} # 对象 设置一个user:1 对象 值为 json字符来保存一个对象
mset user:1:name zhangsan user:1:age 2 # 这里的key是一个巧妙的设计: user:{id}:{filed}
getset db redis # 如果不存在值,返回 nil 。如果存在值,获取原来的值,并设置新值
上面总结了很多String 相关的操作,需要注意的是 value 除了是字符串还可以为我们的数字
string类型 可以使用的场景:
分布式环境下统计在线人数
分布式环境下存储一些共享的数据信息
对象缓存存储
List(列表)
在 redis 中我们可以把 list 构建成 栈 、队列、阻塞队列,这种数据结构本质上都是线性表的变形
所有与列表有关的命令都是用 l 开头,redis 命令不区分大小写
列表的下标是从 左 往 右 开始,左边第一个元素为0
lpush listname one # 将一个值或多个值,插入到链表的头部 (左)
rpush listname zero # 将一个值或多个值,插入到链表的尾部 (右)
lrange listname 0 -1 # 获取,输出listname所有值
lrange listname 0 1 # 获取指定区间中列表的值
lpop listname # 移除列表左边第一个元素
rpop listname # 移除列表右边第一个元素
lindex listname 1 # 通过下表获取 list 中的某一个值
llen listname # 获取列表长度
lrem listname 1 one # 移除集合中指定个数的匹配的 value 值
ltrim listname 0 1 # 集合截断,只保留指定位置的集合元素。
rpoplpush listname listname2 # 移除listname列表右边最后一个元素,将其加入 listname2 的头部
lset listname 0 zero # 替换列表指定下标的值,如果列表不存在报错
linsert listname before|after newvalue oldvalue # 将新值插入指定元素前或者后
list 集合支持元素的指定位置插入,实际上相当于一个链表,可以在节点前后添加元素。在第一次 push 的时候如果 key 存在,则添加元素,key 不存在,创建新链表。如果列表中元素为空,也代表集合不存在。在两边进行插入更行操作相比较于中间进行操作效率更高,省略了查找遍历的时间。
list 可以通过 (lpush ,lpop) 先进后出构建栈数据结构,(lpush rpop)先进先出构建队列数据结构
set(集合)
set 集合是值无序不可重复的,重复的值不会在 set 集合中保存,无序性则指的是存储元素的位置不连续随机,遍历 set 集合的结果随机。
sadd setname "hello" # 向 set 集合中添加元素,集合元素是不可重复的,相同的值不会在存储
smembers setname # 遍历 set 集合(因为无序,所以输出结果每次都不同)
scard setname # 获取set集合中元素个数
srem setname "hello" # 移除集合指定元素
srandmembers setname # 集合中随机抽取一个元素
srandmembers setname 2 # 随机抽取指定数量元素
spop setname # 随机从集合移除一个元素
smove set1 set2 "hello" # 从set1 中移除 hello 添加到set 2
sdiff set1 set2 # 求 set 集合差集
sinter set1 set2 # 求 set 集合交集
sunion set1 set2 # 求 set 集合并集
hash(哈希)
Map集合,key-map! 时候这个值是一个map集合! 本质和String类型没有太大区别,还是一个简单的key-vlaue!
hset hashname field value # set 一个 key-value 的hash 值
hget hashname field # 获取 hash 中一个字段的值
hmset hashname field1 hello field2 world # 设置多个 key-value值
hmget hashname field1 field2 # 获取多个字段值
hgetall hashname # 获取全部的数据
hdel hashname field # 删除hash中的指定的key字段,value 值也相应消失
hlen hashname # 获取 hash 表字段数量
hexists hashname field # 判断hash 中指定字段是否存在
hkeys hashname # 获取 hash 中所有的 key 值
hvals hashname # 获取 hash 中所有的 value 值
hincrby hashname field 1 # 对指定 hash 中的 key 的 value 增 1 (values 值必须为数值)
hincrby hashname field -1 # 增量可以为 负数
hsetnx hashname field hello # 如果不存在则设置,存在则不能设置
hash 适合存储经常发生变动更新的数据 string 类型适合字符串存储
zset(有序集合)
在 set 基础上增加了一个排序值 zset keyname score value,这里 score 就是顺序显示进行设置的编号,可以为成绩,排名,序列号。但是要为可比较的。
zadd setname 1 one # 添加一个元素
zrange setname 0 -1 # 获取设置的所有 set的value值
zrangebyscore setname -inf +inf # 显示全部数据,并按照设置的score从小到大排序,不显示设置的score
zrevrange setname 0 -1 # 显示全部数据,并按照设置的score从大到小进行排序,不显示设置的score
zrangebyscore setname -inf +inf withscore # 显示全部数据,并按照设置的score从小到大排序,显示设置的score
zrangebyscore setname -inf +inf 2500 withscore # 显示小于2500全部数据,并按照设置的score从小到大排序,显示设置的score
zrem setname one # 移除有序集合中的指定元素,one 是zset 中的元素名
zcard setname # 获取有序集合中的个数
zcount setname 1 3 # 获取指定设置score中的元素个数。
三种特殊的数据类型
Bitmap(位存储)
Bitmap 位图,一种数据结构,用来操作二进制位进行记录,就只有 0 和 1两个状态。
Bit 位图可以用来进行统计用户信息,活跃,不活跃,登录,打卡这些信息都只有 0 和 1 两个状态。所以采用 Bitmap来存储十分适合。Bitmap只用来存储 0 或 1 ,这么 1个2进制的比特位,极大减少了存储资源的开销与浪费。
![image-20200921193301184 image-20200921193301184](https://i-blog.csdnimg.cn/blog_migrate/625adb6626ef09665eea6e91b9f1296e.png)
setbit keyname 0 0 # 设置一个 bitmap ,keyname 为bitmap的名称,0为索引下标(只能为数值),0 或 1代表比特为的数据
getbit keyname 0 # 得到 keyname 0号位置的比特数据
bitcount keyname # 统计 keyname Bitmap 中 1 的个数
Hyperloglog(基数)
基数:集合中不重复的元素,和 set 集合一样,保存着不重复的元素。基数相较于set最大的优势占用的内存是固定的。2的64次方个元素。只需要12kb内存。
统计网页的 UV时网页用户访问人次。我们统计的只是用户的人数。传统方式需要保存大量用户 id,我们只是进行简单计数,不需要保存用户 id。但是采用基数会带来 0.81%的误差,如果允许容错,那么一定可以使用 Hyperloglog。如果不允许容错,就使用 set 或者自己的数据类型。当用户多时,可以每天一个 Hyperloglog 基数,然后合并统计。
pfadd keyname a b c d e f # 添加多个元素,也可以单个添加,不会产生覆盖而是元素追加
pfcount keyname # 统计数量
pfmerge keyname1 keyname2 # 合并两个集合
Geospatial 地理位置
这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人。底层存储依然采用的是有序的 zset。
geoadd china:city 116.40 39.90 beijing # 添加城市 参数为 经纬度
geoadd china:city 121.47 31.23 shanghai
geoadd china:city 106.50 29.53 chongqi 114.05 22.52 shengzhen
geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
geopos china:city beijing # 得到城市经纬度坐标
geodist china:city beijing shanghai km # 查看两地的直线距离
georadius china:city 110 30 1000 km # 以110,30 这个经纬度为中心,寻 找方圆1000km内的城市
georadius china:city 110 30 500 km withdist # 显示到中间距离的位置
georadius china:city 110 30 500 km withcoord # 显示城市的定位(经纬度)信息
georadius china:city 110 30 500 km withdist withcoord count 1 # 筛选出指定的结果
georadiusbymember china:city beijing 1000 km # 显示周围城市信息
geohash china:city beijing chongqi # 将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近!
# GEO 底层的实现原理其实就是 Zset!我们可以使用Zset命令来操作geo!
zrange china:city 0 -1 # 查看地图中全部的元素
zrem china:city beijing # 移除指定元素