【redis】redis基本操作和几种数据类型

狂神老师的视频地址:https://space.bilibili.com/95256449

1、基本操作

  • select 3 :选择第三个数据库,一共有15个
  • DBSIZE: 查看当前数据库大小
  • keys * : 查看所有的key
  • flushall: 清空全部
  • flushDB:清空当前数据库
  • EXISTS key:判断key是否存在,1表示存在,0表示不存在
  • move key db:从db中删除key,默认的数据库是1
  • expire key seconds: 设置key过期时间
  • ttl key: 查看key剩余到过期时间
  • type key: 查看key类型

redis是单线程,所有的数据存在内存当中,它的瓶颈是机器的内存和网络带宽。

那么为什么一个单线程的效率要不多线程要快呢?因为多线程是需要CPU调度上下文切换的,这个是比较费时间的,对于内存系统没有CPU调度,那么单线程就是比多线程要快

2、五大数据类型

官网介绍:

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

2.1、String

除了上面的基本命令外:


  • appeend key value: 增加value到key后面,如果key不存在则新加
  • strlen key: 查看key长度

【增减】

  • incr key: 相当于key++,可应用于阅读量这样的需求里面
  • decr key: 相当于key--
  • incrby key nums: 相当于 key += nums
  • decrby key nums: 相当于 key -= nums

【片段】

  • getrange key start end: 获取key的 start到end
  • setrange ket offset value: 指定对应偏移量的位置替换成value

【高级设置】

  • setex key second value: setex expire,设置key的值和过期时间
  • setnx key value: set while not exist,如果不存在设置值,否则设置失败,分布式锁里面经常用

  • mset [key value...]: 批量设置多个key
  • mget [key value...]: 批量获取多个key
  • msetnx [key value...]: 如果不存在,同时设置多个key,这是一个原子性操作,要么全部成功,要么全部失败

【对象】

  • set user:1 {name:wcy,azge:3}: 设置一个user:1 对象,值为json字符串

    这里的key设计的很巧妙,user:{id}:{filed},如此设计在Redis中完全是OK的

    还可以不用json的方式

    这个可以用到什么场景呢?就是key的复用,比如一个用户的粉丝,浏览量, 就可以用这样的结构: uid:123:fans:123 uis:123:readNum:123


【组合命令】

  • getset key value: 获取并设置,如果没有返回nil,如果存在返回之前的值

2.2、List

在redis里面,可以通过双向取的方式将其完成栈、队列、阻塞队列


【压入和弹出】

  • LPUSH key value: 从前边压入值
  • RPUSH key value: 从后边压入值
  • LPOP key: 弹出并返回队列头部
  • RPOP key: 弹出并返回队列底部

【获取】

  • LRANGE key start end: 获取start到end的key值,注意是闭区间,然后0 -1 就是逆序获取
  • LIndex key index: 获取队列的具体位置的值
  • LLen key: 获取k队列的长度

【移除和截断】

  • Lrem key count value: 移除队列中指定个数对应的值(因为list可以重复嘛)
  • Ltrim key start end: 截取指定的长度,注意这个是会修改key的

【组合操作】

  • RPOPLPUSH source destination: 弹出目标队列最后元素压入到新队列,如果新队列没有会自动创建

【指定替换和插入】

  • EXISTS key: 这个之前讲过,一般指定替换前会线判断队列是否存在

  • lset key index value: 给队列的指定下标赋值,队列或位置不存在则报错

  • linsert key before|after pivot value: 在队列pivot值的前后后插入值

【小结】

redis里面的list其实是一个链表,类似linkedlist?

左右都可以插入值,如果key为空,即空链表,等同于key不存在

2.3、Set


【添加和查询】

  • sadd key member [member...]: 添加集合
  • smembers key: 查看集合所有元素
  • srandmember key [count]: 随机抽选出指定数量的元素
  • sismember key member: 查看集合key中是否存在member
  • scard key: 获取集合中个数

【移除】

  • srem key member: 移除key集合中指定元素
  • spop key [count]: 随机删除指定数量元素

【组合命令】

  • smove source destination member: 将元素从原集合移动到目标集合

【差集、并集、交集】

  • sdiff key [key..]: 查询key1中有点key2中没有的
  • sinter key [key..]: 查询key1和key2的并集
  • sunion key [key..]: 查询key1和key2的交集

可以用于共同关注啊,共同好友这样的情景

2.4、Hash(哈希)


【添加和查询】

  • hset key field value: 添加<field,value>值
  • hget key field: 获取key哈希中的field的值
  • hmset key field value [field value..]: 批量添加
  • hmget key field [field..]: 批量获取
  • hgetall key: 获取所有的键值对

【删除】

  • hdel key field: 删除对应键值对

【获取】

  • hlen key: 获取长度
  • hexists key field: 判断指定的字段是否存在
  • hkeys key: 获取哈希所有的field
  • hvals key: 获取哈希所有的value
  • hincrby、hdecrby、hsetnx这些和string的一样,不多赘述

【小结】

Hash更适合对象的存储,尤其是对于用户信息,经常变变更的数据。
虽然string可以通过key:1这样的方式存储对象

2.5、Zset(有序集合)


【添加】

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

【排序】

127.0.0.1:6379> zadd salary 1 1000
(integer) 1
127.0.0.1:6379> zadd salary 2 2000
(integer) 1
127.0.0.1:6379> zadd salary 3 3000
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf #排序
1) "1000"
2) "2000"
3) "3000"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores #排序查询带位置
1) "1000"
2) "1"
3) "2000"
4) "2"
5) "3000"
6) "3"
127.0.0.1:6379> zrevrange salary 0 -1 #逆序查询
1) "3000"
2) "2000"

【查询】

127.0.0.1:6379> zrange salary 0 -1 #查询所有
1) "1000"
2) "2000"
3) "3000"
127.0.0.1:6379> zrem salary 1000  #移除
(integer) 1
127.0.0.1:6379> zcard salary      #查询集合长度
(integer) 2
127.0.0.1:6379> zcount salary 1 2 #查询指定位置有多少元素
(integer) 1

【小结】

有序集合可以应用到例如下面这些情景:

  • 重要消息
  • 带权重的消息

3、三种特殊类型

3.1、geospatial

一共只有六个指令


  • geoadd:插入城市纬、经度

一般是通过java程序导入,这里手动输入演示:

127.0.0.1:6379> geoadd china:city 116.40 39.90 beijin
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
  • geopos:获取指定城市的纬、经度
127.0.0.1:6379> geopos china:city beijin shanghai
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
2) 1) "121.47000163793563843"
   2) "31.22999903975783553"
  • geodist:两个点之间的距离

    单位:
    m(默认单位)、km、mi(英里)、ft(英尺)

127.0.0.1:6379> geodist china:city beijin shanghai
"1067378.7564"
127.0.0.1:6379> geodist china:city beijin shanghai km
"1067.3788"
  • georadius:已给定的纬、经度为中心,找出某一半径的元素
127.0.0.1:6379> georadius china:city 110 30 9000 km #获取110,30这个经纬度为中心找9000km内的城市
1) "shanghai"
2) "beijin"
127.0.0.1:6379> georadius china:city 110 30 9000 km withcoord #显示城市和经纬度
1) 1) "shanghai"
   2) 1) "121.47000163793563843"
      2) "31.22999903975783553"
2) 1) "beijin"
   2) 1) "116.39999896287918091"
      2) "39.90000009167092543"
127.0.0.1:6379> georadius china:city 110 30 9000 km withdist  #显示城市和距离
1) 1) "shanghai"
   2) "1105.9098"
2) 1) "beijin"
   2) "1245.2858"
127.0.0.1:6379> georadius china:city 110 30 9000 km count 1  #显示指定数量城市
1) "shanghai"
  • georadiusbymember:已给定的纬、经度为中心,找出指定距离的城市
127.0.0.1:6379> georadiusbymember china:city beijin 10000 km
1) "shanghai"
2) "beijin"
  • geohash:返回一个位置或多个位置的11位字符串(没什么用)
127.0.0.1:6379> geohash china:city beijin shanghai
1) "wx4fbxxfke0"
2) "wtw3sj5zbj0"

3.2、HyperLogLog

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

什么是基数

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

redis 127.0.0.1:6379> PFADD w3ckey "redis" #添加基数
 
1) (integer) 1
 
redis 127.0.0.1:6379> PFADD w3ckey "mongodb"
 
1) (integer) 1
 
redis 127.0.0.1:6379> PFADD w3ckey "mysql"
 
1) (integer) 1
 
redis 127.0.0.1:6379> PFCOUNT w3ckey  #计算基数个数
 
(integer) 3

redis 127.0.0.1:6379> PFMERGE w3ckey w3ckey1  w3ckey2 #两个并集返回给w3ckey
OK

【小结】

应用场景例如计算访问人数的时候,一个人的重复访问需要去重,一般是用set,但是数量特别多的时候比较麻烦。
而这个场景的核心任务是计数,而不是保存所有的用户id,而HyperLogLog占用内存非常小,有0.81%的错误率(可以忽略不计),就适合这种场景了

3.3、Bitmaps

使用场景:统计用户信息,活跃不活跃、打卡未打卡等等

Bitmaps位图,都是操作二进制来进行记录,只有0和1两个状态


例如记录一周打卡情况

C:\Users\86155>redis-cli
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 0
(integer) 0
127.0.0.1:6379> getbit sign 1  #查看某天打卡情况
(integer) 0
127.0.0.1:6379> getbit sign 3
(integer) 0
127.0.0.1:6379> getbit sign 2
(integer) 1
127.0.0.1:6379> bitcount sign  #查看一周打卡情况
(integer) 2
posted @ 2022-05-10 20:38  吴承勇  阅读(125)  评论(0)    收藏  举报