Redis 狂神篇全(学习中)

本文详细介绍了NoSQL数据库的四大分类及其特点,并深入探讨了Redis的五大数据类型及应用场景,包括字符串、列表、集合、哈希和有序集合等。

一、非关系型数据库Nosql(不仅仅是sql)的四大分类:

1.KV键值对:
新浪:Redis
美团:Redis+Tair
阿里/百度:Redis+memecache

2.文档型数据库(bson 格式和jason一样)
​ MongoDB(一般必须要掌握)
​ MongoDB是一个基于分布式文件存储的数据库,C++存储,主要用来处理大量文档。
​ MongoDB是一个介于关系型数据库和非关系型数据库中中间的产品。
​ MongoDB是非关系型数据库功能最丰富,最像关系型数据库的。

3.列存储数据库
你现在学的MYSQL就是列存储数据库,但是他不是NoSQL
HBase
分布式文件系统

4.图关系数据库
他不是存图形,放的是关系,比如:朋友圈社交网络,广告推荐。
Neo4j,InfoGrid;只要公司需要你也要去学,你是一块砖,哪里需要哪里搬

二、Redis连接与退出

我用的宝塔安装的Redis,就不用配置了。
连接:

redis-cli -p 6379
shutdown  关闭redis
然后到未连接状态,直接exit退出即可
然后可以再次查看进程是否存在
ps -ef|grep redis

三、Redis的五大数据类型

String

set key1 v1  #添加
get key1  #获取key1的值
keys *    #查看所有key
exists key1  #判断是否存在(1/0)
append key1 "hello"   #追加字符串 如果key不存在,就相当于setkey
 strlen key1    # 获取字符串长度
-----------------------------------------------------
 set views 0  # 设置初始浏览量为0
 incr views   #  自增1
 decr views    #	 自减1
 INCRBY views 10   #【步长+增量】
 DECRBY views 10   #【步长-增量】
-----------------------------------------------------
 GETRANGE key1 0 3   # 截取字符串 [0,3]
 GETRANGE key1 0 -1	#  读取全部的字符串 和 get key是一样的
 setrange key2 1 xx  # 替换指定位置开始的字符串!
 -----------------------------------------------------
【setex】:(set with expire)# 设置过期时间
【setnx】:(set if not exist)# 不存在再设置(在分布式锁中会常常使用!)
setex key3 30 "hello"  # 设置key3的值伟hello,30秒后过期
ttl key3 #查看剩余时间,key不存在时返回-2,key没设置时间返回-1

SETNX mykey "redis"  # 如果mykey不存在,创建mykey
-----------------------------------------------------
mset k1 v1 k2 v2 k3 v3  # 同时设置多个值
mget k1 k2 k3  #  同时获取多个值
msetnx k1 v1 k4 v4   # msetnx 是一个原子性的操作 要么一起成功/一起失败!
-----------------------------------------------------
set article:{id}:views 0  # 设置文章编号为id的对象的初始浏览量,为0

List

在redis里面,我们可以把list玩成,栈、队列、阻塞队列!
一边进一边出:队列
一边进不能出:栈
两边都打开都能同时取:阻塞队列

Redis不区分大小写命令!
字符串加不加双引号都没事,会自动识别
 LPUSH list one 	#将一个值或者多个值,插入到列表头部(左)
 LRANGE list 0 -1   #  获取list中的值
 LRANGE list 0 2   # 通过区间获取具体的值!0,2)
 rpush list right # 将一个值或者多个值,插入到列表尾部(右)
 Lpop list  # 从左边移除1ist的第一个元素
 Rpop list  # 从右边移除1ist的第一个元素
 lindex list 1  # 通过下标  获取list中下标为1的元素
 llen list  # 返回列表的长度
 LREM list 2 three # 移除list中的three 并且移除2
【Ltrim】
trim 修剪操作,  list:截断
LTRIM mylist 1 2  #  通过下标截取指定的长度,这个1ist已经被改变了,截断了只剩下截取的元素!
-----------------------------------------------------
【rpoplpush】 移除列表的最后一个元素,将他移动到新的列表中!
RPOPLPUSH mylist(旧) myotherlist(新列) # 移除列表的最后一个元素,将他移动到新的列表中!
-----------------------------------------------------
【lset】  将列表中指定下标的值替换为另外一个值,更新操作
EXISTS list   #  判断列表是否存在
lset list 0 item  # 如果不存在列表我们去更新就会报错||如果存在,更新当前下标的值
(error) ERR no such key
-----------------------------------------------------
【linsert】将某个具体的value插入到列中的某个元素的前面或者后面
LINSERT mylist before(after) "world" "other"

Set

所有的Set命令都是S开头的!

sadd myset "hello"    # set集合中添加元素 注意set中的值不能重复的!
SMEMBERS myset  # 查看指定set的所有值
SISMEMBER myset hello  #  判断某一个值是不是在set集合中!
SCARD myset  #  获取set集合中的内容元素个数!
srem myset hello  #  移除set集合中的指定元素
-----------------------------------------------------
SRANDMEMBER myset  # 随机抽选出一个元素
SRANDMEMBER myset 2  # 随机抽选出指定个数的元素
-----------------------------------------------------
spop myset  #  随机删除key   附:栈的弹出函数pop()
smove myset myset2 kuangshen  # 将一个指定的值,移动到另外一个set集合!
sdiff key1 key2    #  差集  注意是以key1为参照物
1) "b"
2) "a"
sinter key1 key2    #  交集  共同好友就可以这么实现
sunion key1 key2   #  并集   
微博,A用户将所有关注的人放在一个set集合中!将它的粉丝也放在一个集合中!
共同关注,共同爱好,二度好友,推荐好友!(六度分割理论)

Hash(哈希)

你可以理解成map集合 key-value形式,只是这个value是一个map集合的形式
本质和String类型没有太大区别,还是一个简单的key-vlaue!
hset myhash field1 kuangshen  # set 一个具体 key-value
hget myhash field1  # 获取1个字段值
hmset myhash field1 hello field2 world  # set 多个具体 key-value 存在则覆盖
hkeys myhash  # 只获取所有key
hvals myhash  # 只获取所有value
hmget myhash field1 field2   # 获取多个字段值
hgetall myhash  # 获取哈希中全部的数据key和value
hlen myhash  # 获取哈希表字段的数量
hdel myhash field1  # 删除hash指定key字段:对应的value值也就消失了
hexists myhash field2  #  判断hash中指定字段是否存在!
hincrby myhash field3 1  #  设置自增1
hincrby myhash field3 -1  # 设置自减
hsetnx myhash field4 hello  #  如果不存在field4则可以设置valus值为hello||如果存在则不能设置

Zset(有序集合)

zadd myset 1 one # 添加1个值
zrange myset 0 -1 # 遍历打印所有数据
ZRANGEBYSCORE salary -inf +inf  # 显示全部用户 【从小到大】
ZREVRANGE salary 0 -1  # 【从大到小】 进行排序  rev反转的意思
ZRANGEBYSCORE salary -inf 2500 withscores # 显示工资小于2500的升序排列
zunionstore unkey12 2 k1 k2 #合并两个集合k1,k2
zrem salary xiaoming  # 移除有序集合中的元素
zcard salary  # 获取有序集合中的个数
zcount myset 1 3  # 获取指定区间的成员数量

三种特殊数据类型

geospatial 地理位置空间
​ 官方网址:https://www.redis.net.cn/order/3689.html
朋友的定位,附近的人,打车距离计算?
Redis 的 Geo 在Redis3.2版本就推出了!这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人!
可以查询一些测试数据:https://jingweidu.51240.com/

# getadd 添加地理位置
# 规则:南北两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!
# 参数 key 值(纬度、经度、名称)
# 有效的经度从-180度到180度。
# 有效的纬度从-85.05112878度到85.05112878度。
geoadd china:city 116.40 39.90 beijing

# geopos
geopos china:city hangzhou beijing  # 获取指定的城市的经度 和 维度!
geodist 返回两个给定位置之间的距离

m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
geodist china:city hangzhou beijing km
# georadius 以(给定的经纬度)为中心, 找出某一半径内的元素
GEORADIUS china:city 110 30 1000 km   # 以110,30这个经纬度为中心,寻找方圆1000km内的城市 
GEORADIUS china:city 110 30 500 km withdist # 显示到中间位置的直线距离 半径500km
 GEORADIUS china:city 110 30 500 km withcoord # 显示到中心距离半径500km的城市 +  经纬度信息
 GEORADIUS china:city 110 30 500 km withcoord withdist count 3 # 筛选出指定结果  
GEORADIUSBYMEMBER
# 找出位于指定范围内的元素,中心点是由给定的位置元素决定
GEORADIUSBYMEMBER china:city beijing 1000 km

GEO 底层的实现原理:Zset! 我们可以用Zset命令来操作Geo

hyperloglog 位图

什么是基数?
基数(一个集合中不重复的元素)
统计疫情感染人数:存身份标识码
优点:占用的内存是固定的,2^64不同的元素的技术,只需要废12kb内存。如果要从内存角度来比较的话Hyperloglog首选!
如果允许容错,那么一定可以使用Hyperloglog
如果不允许容错,就使用 set 或 自己的数据类型 即可

pfadd mykey a b c d e f g h i j  # 创建第一组元素 mykey
PFCOUNT mykey  # 统计mykey元素的基数数量
PFMERGE mykey3 mykey mykey2 # 合并两组 mykey mykey2=>mykey3并集

bitmap 位图

面试题:如何筛选用户是最快的,0-1-0-1是最快的。

统计疫情感染人数:0 0 1 0 0

14亿个中国人,设14亿个0,被感染了设为1.
统计用户信息,活跃、不活跃。登录、未登录。打卡,钉钉打卡打卡!只要2个状态的,都可以用Bitmaps来处理。

userid status day 这样非常麻烦
​ Bitmaps位图,数据结构!都是操作二进制位来进行记录,就只有0和1两个状态!

​ 365天=365bit 1字节=8bit 46个字节左右!


【getbit、setbit】
 setbit sign 3 1  # 输入某一天是否打卡
 setbit sign 2 0
 getbit sign 6   # 查看某一天是否打卡
【bigcount】
 bitcount sign   # 查看是否全勤 统计操作,统计打卡的天数

事务

原子性:要么同时成功,要么同时失败。

redis单条命令是保障原子性的, 但是事务是不保证原子性的

Redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程的中,会按照顺序执行!

  • 一次性执行
  • 顺序性
  • 排他性

不允许别人感染

------ 队列 set set set 执行 ------

Redis事务没有隔离级别的概念
所有的命令在事务中,并没有直接被执行!
在队列中并没有执行
只有发起执行命令的时候才会执行!Exec
redis的事务:

  • 开启事务(multi)
  • 命令入队(…)
  • 执行事务(exec)
 multi    # 开启事务
set k1 v1 语句
.
.
DISCARD  #  取消事务
exec   # 执行事务
编译型异常(代码有问题!命令有错!),事务中所有的命令都不会被执行
运行时异常(1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的 错误命令抛出异常

redis还可以做监控

监控!Watch监视器

悲观锁:
很悲观,认为什么时候都会出问题,无论做什么都会加锁!

乐观锁:
很乐观,认为什么时候都不会出问题,所以不会上锁!

更新的时候去判断一下,在此期间是否有人修改过这个数据,mysql中的version字段!

  • 获取version
  • 更新的时候比较version

我们基本大部分使用乐观锁为主,很少使用悲观锁,因为效率太低了

node1:6379> set money 100
OK
node1:6379> set out 0
OK
node1:6379> watch money  # 监视money
OK
node1:6379> MULTI
OK
node1:6379> DECRBY money 10
QUEUED
node1:6379> INCRBY out 10
QUEUED
##############  另一线程修改数据    ##########
node1:6379> set money 1000
OK
##############  原线程执行    ##########
node1:6379> exec  # 执行之前,另外线程修改了我们的值,就会导致执行失败
(nil)

############# 还想继续执行怎么办?   #############
node1:6379> unwatch   # 先解锁
OK
node1:6379> WATCH money  # 重新加锁,获取最新version 再操作即可
OK
node1:6379> exec # 对比监视的值是否发生了变化,如果没有变化,那么可以执行成功,如果变了就执行失败

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值