一文让你彻底懂Redis

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1.NoSQL介绍

1.1 什么是NoSQL

  • 非关系型数据库就是NoSQL关系型数据库代表MySQL。

  • 对于关系行数据库是需要把数据存储到库、表、行、字段里查询的时候根据条件一行一行地去匹配当量非常大的时候就很耗费时间和资源尤其是数据是需要从磁盘里去检索 (如图)。

  • NoSQL数据库存储原理非常简单(典型的数据类型为k-v),不存在繁杂的关系链比如mysql查询的时候需要找到对应的库、表(通常是多个表)以及字段。

  • NoSQL数据可以存储在内存里查询速度非常快。

  • NoSQL在性能表现上虽然能优于关系型数据库但是它并不能完全替代关系型数据库。

  • NoSQL因为没有复杂的数据结构扩展非常容易支持分布式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lhRwZ9KP-1650532184594)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220420192317386.png)]

图一 关系型数据库查询复杂

1.2 常见NoSQL数据库

  1. 键值数据库redis、memcached适合储存用户信息应用场景比如内存缓存,会话、配置文件、参数、购物车等等。往往是频繁读写、拥有简单数据模型k-v形式的的应用。其优点扩展性好灵活大量操作性能高。缺点数据无结构化只能当作字符串或者二进制数据通常只能通过键值来查询。

  2. 文档数据库mongodb将数据以文档的形式储存。应用场景比如Web应用存储面向文档或者类似半结构化的数据<key,value> value是JSON结构的文档。 其优点结构灵活可以根据value构建索引。**其缺点**缺乏统一查询语法。

  3. 列簇数据库HBase等应用场景分布式数据存储与管理以列簇式存储将统一列数据存储在一起。其优点是可扩展性强查找快复杂性低。缺点是功能局限不支持事务的一致性。

  4. 图形数据库Neo4J、Infinite Graph、OrientDB应用场景为社交网络推荐系统其多为图结构。优点是支持复杂的语法其缺点是复杂性高只能支持一定的数据规模。

image-20220420195905419 image-20220420195822337

由图可知当业务场景越来越复杂的时候仅仅是mysql是满足不了我们的需求的所以我们需要学习nosql。

1.3 总结

  • 关系型数据库与NoSQL数据库并非对立而是互补的关系即通常情况下使用关系型数据库在适合使用NoSQL的时候使用NoSQL数据库让NoSQL数据库对关系型数据库的不足进行弥补。
  • 一般会将数据存储在关系型数据库中在nosql数据库中备份存储关系型数据库的数据。

2.Redis入门以及环境搭建

2.1 概述

Redis是什么

RedisRemote Dictionary Server )即远程字典服务。

它是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库并提供多种语言的API。为了保证效率数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件并且在此基础上实现了master-slave(主从)同步。

image-20220420203940647

Redis 是一个开源BSD许可的内存中的数据结构存储系统它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构如 字符串strings 散列hashes 列表lists 集合sets 有序集合sorted sets 与范围查询 bitmaps hyperloglogs 和 地理空间geospatial 索引半径查询。 Redis 内置了 复制replicationLUA脚本Lua scripting LRU驱动事件LRU eviction事务transactions 和不同级别的 磁盘持久化persistence 并通过 Redis哨兵Sentinel和自动 分区Cluster提供高可用性high availability。

Redis能该干什么

  1. 内存存储、持久化内存是断电即失的所以需要持久化RDB、AOF
  2. 高效率、用于高速缓冲
  3. 发布订阅系统
  4. 地图信息分析
  5. 计时器、计数器(eg浏览量,评论数点赞数等)
  6. 分布式数据共享如分布式集群架构中的session分离
  7. 消息队列
  8. 分布式锁

Redis的特性

  • 多样的数据类型
  • 持久化
  • 集群
  • 事务

2.2 Redis环境搭建

官网https://redis.io/

中文网http://www.redis.cn/

注意Windows版本的Redis已经很久没更新了更多的还是使用Linux服务器使用Redis。

2.2.1 Windows系统下安装

下载地址https://github.com/dmajkic/redis

  1. 解压安装包

    image-20220420200926058
     * redis.windows.conf配置文件
     * redis-cli.exeredis的客户端
     * redis-server.exeredis服务器端
    
  2. 双击redis-server.exe

  3. 启动redis-cli.exe测试 输入如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LHdsE52l-1650532184595)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220420201057275.png)]

2.2.2 Linux下配置Redis

注意 这里我们使用centos7系统 (可以使用Unbantu但不建议使用centos6或8) 如何购买和使用阿里云服务器、腾讯云服务器和虚拟服务器请参考csdn

  1. 到redis官网下载安装包 redis-6.0.8.tar.gz 通过xftp工具上传至/opt目录下或者data目录下

当然也可以通过命令的方式下载

wget https://download.redis.io/releases/redis-6.2.6.tar.gz
image-20220420224803422
  1. 通过xshell解压Redis的安装包 (注意:如果没有使用共xshell和xftp的同学请自行百度很容易上手)

在opt/目录下

tar -zxvf redis-6.2.6.tar.gz
image-20220420224917604

安装redis 6需要相匹配版本的gcc必须是gcc 5.0以上我这里版本就不匹配需要重新下载gcc与gcc-c++。

gcc -v
image-20220420230214456
# 安装scl 进入刚解压的文件夹内/opt/redis-6.2.6  cd redis-6.2.6
$ yum -y install centos-release-scl
# 升级gcc到9版本
$ yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
# 长期使用gcc 9版本的话,将执行命令输入到环境变量配置
$ echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
# 编译安装redis,存放在local目录下
$ make PREFIX=/local/redis-6.2.6
$ make install

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wxkejtW4-1650532184595)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220420231809090.png)]

现在我们进入安装好的文件夹内(/local/redis-6.2.6/bin)

执行命令,出现下图说明安装成功

redis-server
image-20220420232045080

ctrl+c 返回命令行

注意:为了让其能够在后台自动启动我们将之前解压的文件夹中的redis.conf复制到当前目录

mkdir myconfig
cp /opt/redis-6.2.6/redis.conf myconfig
cd myconfig
image-20220420233010851

修改redis.conf

vim redis.conf
使用 i 进行插入数据
daemonize yes (能让服务端一直开启)
并注释掉#bind 127.0.0.1 -::1这一行使其能够被外部访问
先esc 后 :wq 返回命令行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fdnBJPzL-1650532184596)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220420233342824.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xS5LyWzz-1650532184596)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220420233400424.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1sgg6kI-1650532184596)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220420234753598.png)]

执行ps -ef|grep redis命令找到已启动的redis服务使用kill命令杀掉redis服务进程。

ps -ef|grep redis 查看redis进程
kill -9 3763 表示进程号
image-20220420235042706
redis-server myconfig/redis.conf
image-20220421001304101

再另一个窗口进行交互

image-20220421001608980

关闭服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O3x4h1kg-1650532184596)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421001903616.png)]

到这里就已经大功告成了~

2.3 测试性能

redis-benchmark Redis官方提供的性能测试工具参数选项如下

redis-benchmark [-h ] [-p ] [-c ] [-n ] [-k ]

序号选项描述默认值
1-h 指定服务器主机名(默认 127.0.0.1)
2-p 指定服务器端口(默认 6379)
3-s 指定服务器 socket
4-a Redis 认证密码
5-c 指定并发连接数(默认 50)
6-n 指定请求数(默认 100000)
7-d 以字节的形式指定 SET/GET 值的数据大小(默认 2)
8–dbnum 选择指定的数据库号(默认 0)
9-k 1=keep alive 0=reconnect(默认 1)
10-r SET/GET/INCR 使用随机 key, SADD 使用随机值
11-P 通过管道传输 请求 (no pipeline)
12-q退出仅显示 query/sec 值
13–csv以 CSV 格式输出
14-l生成循环永久执行测试
15-t 仅运行以逗号分隔的测试命令列表
16-IIdle 模式仅打开 N 个 idle 连接并等待

2.3.1 简单测试

# 测试100个并发连接 100000请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000

一个窗口开启服务器

image-20220421103147975

另一个窗口进行测试

image-20220421103529154

3. Redis基础知识

3.1 Redis基本操作

1.切换数据库(redis默认有16个数据库默认使用的是第0个)

select index 进行切换数据库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-axzffVz7-1650532184597)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421103837103.png)]

2.查看数据库大小

dbsize

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GOWQ1vrS-1650532184597)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421104003099.png)]

3.清空当前数据库(3号数据库)

flushdb

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Or6IoSRN-1650532184597)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421104116967.png)]

4.清空所有数据库

flushall

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0QgWhFj9-1650532184598)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421104313649.png)]

3.2 Redis是单线程的

redsi很快redis基于内存操作cpu不是redis性能瓶颈redis的瓶颈是根据机器的内存和网络带宽既然可以使用单线程来实现就使用单线程。redis是c语言写的官方数据是100000+的QPS。

redis为什么单线程还这么快
1.误区高性能的服务器一定是多线程的
2.误区二多线程一定比单线程高
核心redis将所有数据全部放在内存中所以说使用单线程去操作效率高多线程cpu上下文切换耗时操作对于内存系统来说如果没有上下文切换效率是最高的多次读写都是在一个cpu上的在内存情况下这个就是最佳方案

4.Redis命令操作

4.1 key通用命令

下列操作以string类型为演示(其它基本类型也适用)

1.查找所有的键

keys *

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UIITDYl1-1650532184598)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421110030947.png)]

2.判断键是否存在

exists key (键名)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-39tk0gtx-1650532184598)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421110213309.png)]

3.获取键对应的值

get key

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w9NIVyDh-1650532184598)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421110550332.png)]

4.设置键过期时间

expire key 10 (设置该键10秒钟之后过期)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fxsUgogT-1650532184599)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421110645073.png)]

5.查看键值剩余过期时间 -2表示已经过期

ttl key

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-emNFKV6R-1650532184604)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421110731287.png)]

再使用get age就会返回空了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hg8pVEHp-1650532184605)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421110826519.png)]

Redis的key通过TTL命令返回key的过期时间一般来说有3种

  1. 当前key没有设置过期时间所以会返回-1.
  2. 当前key有设置过期时间而且key已经过期所以会返回-2.
  3. 当前key有设置过期时间且key还没有过期故会返回key的正常剩余时间.

6.对key重命名

rename key newkey

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LyG5w9qQ-1650532184605)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421111525331.png)]

7.删除key

del key

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AQnxFJ2A-1650532184605)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421112219405.png)]

8.设置键值

set key value

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y5pVxMPS-1650532184606)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421112542303.png)]

9.获取键对应value的类型

type key

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hQSPWbTV-1650532184606)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421145223914.png)]

更多命令的学习去请查看https://www.redis.net.cn/order/

4.2 redis五大基本数据类型

4.2.1 概述

redis的数据结构

  • redis存储的是key,value格式的数据其中key都是字符串value有5种不同的数据结构

  • value的数据结构

    1. 字符串类型 string
    2. 哈希类型 hash map格式
    3. 列表类型 list linkedlist格式。支持重复元素
    4. 集合类型 set 不允许重复元素
    5. 有序集合类型 sortedset不允许重复元素且元素有顺序
    • 上面这五种是基本的数据类型。

4.2.2 字符串类型 string

1. 存储 set key value
2. 获取 get key
3. 删除 del key
4. 追加:  append key value
5. 判长:  strlen key

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PcDUbAm7-1650532184606)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421115729865.png)]

案例一 浏览量变化

set views 0
get views 
incr views #浏览量自增 1
get views
decr views #自减 1
get views
incrby views 10 #设置自增步长为10
decrby views 10 #设置自减步长为10

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-un8GiyFc-1650532184606)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421120415963.png)]

案例二: 字符串范围 range

set message "hello,world" 
get message
getrange message 0 3 # 截取字符串 [0,3]
getrange message 0 -1 # 获取全部的字符串 和 get message是一样的
setrange message 6 error # 替换指定位置开始的字符串
get message

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R2xXkQaa-1650532184606)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421121513717.png)]

案例三: 过期时间设置

# setex (set with expire) # 设置过期时间
# setnx (set if not exist) # 不存在在设置 在分布式锁中会常常使用

setex key 30 "hello"   # 设置key3 的值为 hello,30秒后过期
ttl key
get key
setnx mykey "redis" #如果mykey不存在则创建 如果存在则失败
keys *

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M3mYSCKV-1650532184607)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421123846481.png)]

案例四同时设置或修改多值

mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
keys *
mget k1 k2 k3 # 同时获取多个值
msetnx k1 v1 k4 v4 # msetnx 是一个原子性的操作要么一起成功要么一起失败
get k4
set user:1 {name:zhangsan,age:3} # 设置一个user:1 对象 值为 json字符来保存一个对象
# 这里的key是一个巧妙的设计 user:{id}:{filed} , 如此设计在Redis中是完全OK了
mset user:1:name zhangsan user:1:age 2
mget user:1:name user:1:age

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6eysE4Bv-1650532184607)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421124723686.png)]

案例五先获得再设置修改

getset db redis # 如果不存在值则返回 nil
get db
getset db mongodb # 如果存在值获取原来的值并设置新的值
get db

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vfhc1gUk-1650532184607)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421124812412.png)]

String的使用场景计数器(value为数字)统计多个单位的数量粉丝数浏览数对象缓存存储等

4.2.3 List(列表)

在redis里面我们可以把list玩成 栈、队列、阻塞队列

注意所有的list命令都是用l开头的Redis不区分大小命令。

1.增加数据

lpush mylist one # 将一个值或者多个值插入到列表头部 左
lpush mylist two
lpush mylist three
lrange mylist 0 -1 #获取mylist所有的值
rpush mylist four # 将一个值或者多个值插入到列表位部 右

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wEOK8VMC-1650532184607)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421131725015.png)]

2.删除数据

lrange mylist 0 -1
lpop mylist  # 移除list的第一个元素
rpop mylist  # 移除list的最后一个元素
lrange mylist 0 -1
lrem mylist 1 one # 移除list集合中指定个数的value精确匹配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HmDYmJDq-1650532184607)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421132458875.png)]

3.查找数据

lindex mylist 0 # 通过下标获得 list 中的某一个值
lpush mylist one
llen mylist #获取列表的长度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87bfp6q9-1650532184608)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421132756167.png)]

4.其它命令

trim 修剪
rpoplpush # 移除列表的最后一个元素将他移动到新的列表中
lset #将列表中指定下标的值替换为另外一个值更新操作
linsert # 将某个具体的value插入到列把你中某个元素的前面或者后面

ltrim mylist 1 2 # 通过下标截取指定的长度这个list已经被改变了截断了只剩下截取的元素
rpoplpush mylist myotherlist
lset mylist 0 zero # 如果不存在列表,更新就会报错 (将下标为0的元素替换为zero)
linsert mylist before "zero" "zero1"
linsert mylist after "two" "tree"

小结

  • 他实际上是一个双向链表before Node after leftright 都可以插入值
  • 如果key 不存在创建新的链表
  • 如果key存在新增内容
  • 如果移除了所有值空链表也代表不存在
  • 在两边插入或者改动值效率最高 中间元素相对来说效率会低一点~

消息排队消息队列 Lpush Rpop 栈 Lpush Lpop

4.2.4 Set集合

set值是不能重复的

常见操作

1. 存储sadd key value
sadd myset a
2. 获取smembers key #获取set集合中所有元素
smembers myset 
3. 判断sismember myset a #判断某一值是否存在
4. 判长scard myset #判断myset有多少元素
3. 删除srem key value #删除set集合中的某个元素	
srem myset a
4. 随机抽取srandmembers myset  #随机抽取一个元素
5. 随机抽取若干srandmembers myset x #随机抽取x个元素
6. 随机删除: spop myset #随机删除set集合中的元素
7. 移动元素smove myset myset2 "dx" # 将一个指定的值移动到另外一个set集
数字集合:
8. sdiff key1 key2 #求差集
9. sinter key1 key2 #求交集
10.sunion key1 key2 #求并集

小结

常见案例微博A用户将所有关注的人放在一个set集合中将它的粉丝也放在一个集合中共同关注共同爱好二度好友推荐好友六度分割理论

4.2.5 Hash(哈希)

Map集合key-map! 时候这个值是一个map集合 本质和String类型没有太大区别还是一个简单的key-vlaue

常见操作

1. 存储 hset key field value
2. 获取 
    * hget key field: 获取指定的field对应的值
    * hgetall key获取所有的field和value
3. 删除 hdel key field
4. 设置:
    * hmset myhash field1 hello field2 world # set多个 key-vlaue
    * hset myhash field1 hello1 #设置一个字段的value
    * hsetnx myhash field4 hello # 如果不存在则可以设置
5. 获取字段操作
	* hlen myhash # 获取hash表的字段数量
	* hexists myhash field1 # 判断hash中指定字段是否存在
	* hkeys myhash # 只获得所有field
	* hvals myhash # 只获得所有value
(incr decr)
    * hset myhash field3 5 #指定增量
    * hincrby myhash field3 1 #字段的值增加1

小结

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

4.2.6 Zset有序集合

有序集合类型 sortedset不允许重复元素且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

常见操作

1. 存储zadd key score value
2. 获取zrange key start end [withscores]
3. 删除zrem key value
4. 排序zrangebyscore key min max
	*zrangebyscore key -inf +inf # 显示全部的用户 从小到大
	*zrevrange salary 0 -1 # 从大到进行排序
	*zrangebyscore key -inf +inf withscores# 显示全部的用户 从小到大,并带上成绩
5. 获取指定区间的数量zcount key min max# 获取指定区间的成员数量

其与的一些API通过我们的学习吗你们剩下的如果工作中有需要这个时候你可以去查查看官方文档
案例思路set 排序 存储班级成绩表工资表排序
普通消息1 重要消息 2带权重进行判断
排行榜应用实现取Top N 测试

4.3 三种特殊数据类型

4.3.1 Geospatial 地理位置

朋友的定位附近的人打车距离该如何计算
Redis 的 Geo 在Redis3.2 版本就推出了 这个功能可以推算地理位置的信息两地之间的距离方圆几里的人

可以查询一些测试数据http://www.jsons.cn/lngcodeinfo/0706D99C19A781A3/

API

1.geoadd 将指定的地理空间位置经度、纬度、名称添加到指定的key中
2.geopos 从key里返回所有给定位置元素的位置经度和纬度
3.geodist 返回两个给定位置之间的距离
4.Geohash 返回一个或多个位置元素的 Geohash 表示
5.Georadius 以给定的经纬度为中心 找出某一半径内的元素
6.Georadiusbymember 找出位于指定范围内的元素中心点是由给定的位置元素决定

官方文档https://www.redis.net.cn/order/3685.html

getadd

# getadd 添加地理位置
# 规则两级无法直接添加我们一般会下载城市数据直接通过java程序一次性导入
# 有效的经度从-180度到180度。
# 有效的纬度从-85.05112878度到85.05112878度。
# 当坐标位置超出上述指定范围时该命令将会返回一个错误。
# 127.0.0.1:6379> geoadd china:city 39.90 116.40 beijin
(error) ERR invalid longitude,latitude pair 39.900000,116.400000
# 参数 key 值
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqi 114.05 22.52 shengzhen
(integer) 2
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 2

getpos

获得当前定位一定是一个坐标值

127.0.0.1:6379> GEOPOS china:city beijing # 获取指定的城市的经度和纬度
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
127.0.0.1:6379> GEOPOS china:city beijing chongqi
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
2) 1) "106.49999767541885376"
2) "29.52999957900659211"

GEODIST

两人之间的距离
单位

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。
127.0.0.1:6379> GEODIST china:city beijing shanghai km # 查看上海到北京的直线距离
"1067.3788"
127.0.0.1:6379> GEODIST china:city beijing chongqi km # 查看重庆到北京的直线距离
"1464.0708"

georadius 以给定的经纬度为中心 找出某一半径内的元素

我附近的人 获得所有附近的人的地址定位通过半径来查询
获得指定数量的人200
所有数据应该都录入china:city 才会让结果更加请求

127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km # 以11030 这个经纬度为中心寻
找方圆1000km内的城市
1) "chongqi"
2) "xian"
3) "shengzhen"
4) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km
1) "chongqi"
2) "xian"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist # 显示到中间距离的位置
1) 1) "chongqi"
2) "341.9374"
2) 1) "xian"
2) "483.8340"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord # 显示他人的定位信息
1) 1) "chongqi"
2) 1) "106.49999767541885376"
2) "29.52999957900659211"
2) 1) "xian"
2) 1) "108.96000176668167114"
2) "34.25999964418929977"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist withcoord count 1 #筛选出指定的结果
1) 1) "chongqi"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist withcoord count 2
1) 1) "chongqi"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
2) 1) "xian"
2) "483.8340"
3) 1) "108.96000176668167114"
2) "34.25999964418929977"

GEORADIUSBYMEMBER

# 找出位于指定元素周围的其他元素
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km
1) "beijing"
2) "xian"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city shanghai 400 km
1) "hangzhou"
2) "shanghai"

GEOHASH 命令 - 返回一个或多个位置元素的 Geohash 表示

该命令将返回11个字符的Geohash字符串

# 将二维的经纬度转换为一维的字符串如果两个字符串越接近那么则距离越近
127.0.0.1:6379> geohash china:city beijing chongqi
1) "wx4fbxxfke0"
2) "wm5xzrybty0"

GEO 底层的实现原理其实就是 Zset我们可以使用Zset命令来操作geo

127.0.0.1:6379> ZRANGE china:city 0 -1 # 查看地图中全部的元素
1) "chongqi"
2) "xian"
3) "shengzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"
127.0.0.1:6379> zrem china:city beijing # 移除指定元素
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "chongqi"
2) "xian"
3) "shengzhen"
4) "hangzhou"
5) "shanghai"

4.3.2 Hyperloglog

什么是基数

A {1,3,5,7,8,7}
B{13,5,7,8}
基数不重复的元素 = 5可以接受误差

简介

Redis 2.8.9 版本就更新了 Hyperloglog 数据结构
Redis Hyperloglog 基数统计的算法
优点占用的内存是固定2^64 不同的元素的技术只需要废 12KB内存如果要从内存角度来比较的
话 Hyperloglog 首选

网页的 UV 一个人访问一个网站多次但是还是算作一个人

传统的方式 set 保存用户的id然后就可以统计 set 中的元素数量作为标准判断 !

这个方式如果保存大量的用户id就会比较麻烦我们的目的是为了计数而不是保存用户id
0.81% 错误率 统计UV任务可以忽略不计的

测试使用

127.0.0.1:6379> PFadd mykey a b c d e f g h i j # 创建第一组元素 mykey
(integer) 1
127.0.0.1:6379> PFCOUNT mykey # 统计 mykey 元素的基数数量
(integer) 10
127.0.0.1:6379> PFadd mykey2 i j z x c v b n m # 创建第二组元素 mykey2
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 9
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2 # 合并两组 mykey mykey2 => mykey3 并集
OK
127.0.0.1:6379> PFCOUNT mykey3 # 看并集的数量
(integer) 15

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

4.3.3 Bitmap

这些在生活中或者开发中都有十分多的应用场景学习了就是就是多一个思路

位存储

统计用户信息活跃不活跃 登录 、 未登录 打卡365打卡 两个状态的都可以使用
Bitmaps
Bitmap 位图数据结构 都是操作二进制位来进行记录就只有0 和 1 两个状态

365 天 = 365 bit 1字节 = 8bit 46 个字节左右! 极大了减少存储。

使用bitmap 来记录 周一到周日的打卡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w2KD5Ex5-1650532184608)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220421170629813.png)]

查看某一天是否有打卡

127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 6
(integer) 0

统计操作统计 打卡的天数

127.0.0.1:6379> bitcount sign # 统计这周的打卡记录就可以看到是否有全勤
(integer) 3
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis

“一文让你彻底懂Redis” 的相关文章