Redis6(一)

本博客为尚硅谷课程笔记,课程来源:【尚硅谷】Redis 6 入门到精通 超详细 教程_哔哩哔哩_bilibili

本博客参考内容:
https://blog.csdn.net/weixin_47872288/article/details/118410080
https://zhangc233.github.io/2021/05/02/Redis/#HyperLogLog

在这里插入图片描述

1. NoSQL数据库简介

Not Only SQL,非关系型数据库

NoSQL有什么用:

  1. 解决CPU和内存压力
  2. 解决IO压力

NoSQL数据库特点:

  1. 非关系型数据库,不依赖业务逻辑数据库存储,以key-value存储,因此大大增加了数据库的扩展能力
  2. 不遵守SQL标准
  3. 不支持ACID(原子性、隔离性、一致性、持久性)
  4. 远超于SQL的性能

适用于:

  1. 高并发读写
  2. 海量数据读写
  3. 数据可扩展

不适用于场景:

  1. 需要事务支持
  2. 需要基于SQL结构化查询存储

NoSQL优点:

  1. 缓存数据库,完全在内存中,速度快,数据结构简单
  2. 减少io操作,数据库和表拆分,虽然破坏业务逻辑,即外加一个缓存数据库,提高数据库速度,也可以用专门的存储方式,以及针对不同的数据结构存储

常见的NoSQL数据库

  1. Memcache:不支持持久化
  2. Redis:支持持久化
  3. MongoDB:文档数据库
    在这里插入图片描述


2. Redis安装与配置

0. Redis概述

redis特性:

  • Redis是一个开源key-value存储系统
  • 支持string,list,set,zset,hash类型
  • 这些数据类型都支持push/pop,add/remove,取交集并集等,这些操作都是原子性
  • 支持不同方式的排序
  • 数据都是缓存在内存
  • 实现了master-slave主从同步

1. 下载与安装

https://blog.csdn.net/qq_39236499/article/details/124383092

2. 应用场景

  • 配合关系型数据库做高速缓存
    在这里插入图片描述
  • 多样的数据结构存储持久化数据
    在这里插入图片描述

3. set插入数据报错解决方法

参考博客:

https://blog.csdn.net/Sophia_0331/article/details/107779165

https://blog.csdn.net/zdyueguanyun/article/details/83449912

在这里插入图片描述

解决方法:

config set stop-writes-on-bgsave-error no

3. 常用五大数据类型

0. Redis相关知识

  • 登录redis客户端:/usr/local/bin/redis-cli

  • Redis端口:6379

  • Redis默认16个数据库,默认使用0号数据库

  • Redis是单线程+多路IO复用

在这里插入图片描述

0.1 数据操作

1、插入数据

set key value

2、查看当前库的所有key

keys *

3、是否存在当前键,存在返回1,否则返回0

exists key

4、删除键值对

del key

方法二:删除键值对,根据value选择非阻塞删除

unlink key

5、查看键对应的值的类型

type key

6、给键设置过期时间,time以秒为单位

expire key time

7、查看键多长时间过期:返回结果-1表示永不过期,-2表示已过期

ttl key

例:

zdb@zdb-virtual-machine:~$ /usr/local/bin/redis-cli

//查询所有键
127.0.0.1:6379> keys *
(empty array)

//插入数据
127.0.0.1:6379> set k1 lucy
OK
127.0.0.1:6379> set k2 mary
OK
127.0.0.1:6379> set k3 jack
OK
    
//查询数据
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"

//判断是否存在
127.0.0.1:6379> exists k1
(integer) 1
127.0.0.1:6379> exists k4
(integer) 0

//查询类型
127.0.0.1:6379> type k1
string
    
//删除数据    
127.0.0.1:6379> del k3
(integer) 1
127.0.0.1:6379> unlink k2
(integer) 1

//设置定时器    
127.0.0.1:6379> expire k1 10
(integer) 1
127.0.0.1:6379> ttl k1
(integer) 4
127.0.0.1:6379> ttl k1
(integer) -2

0.2 库操作

1、选择库,默认库为0号

select 库号

2、查看当前数据库的key数量

dbsize

3、清空当前库

flushdb

4、清空所有库

flushall

例:

# 选择库
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 0
OK

# 查看数据库的key数量
127.0.0.1:6379> dbsize
(integer) 0

127.0.0.1:6379> keys *
(empty array)

# 清除当前库
127.0.0.1:6379> flushdb
OK

1. String字符串

  • 一个key对应一个value
  • String是 二进制安全的,String可包含任何数据,比如jpg图片转换成string存储
  • String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M
  • 动态的字符串,会扩容

1.1 常用命令

  • 获取值:get key

  • 在值尾部追加元素:append key add_value

  • 获取值的长度:strlen key

  • 当key不存在,才存入key-value对:setnx key value

  • value增1:incr key

  • value减1:decr key

  • value增一个常数:incrby key 步长

  • value减一个常数:decr key 步长

127.0.0.1:6379> set k1 v100
OK
127.0.0.1:6379> set k2 v200
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"

# 获取对应key的value
127.0.0.1:6379> get k1
"v100"

# 设置
127.0.0.1:6379> set k1 v1100
OK
127.0.0.1:6379> get k1
"v1100"

# 追加
127.0.0.1:6379> append k1 bac
(integer) 8
127.0.0.1:6379> get k1
"v1100bac"
127.0.0.1:6379> strlen k1
(integer) 8

# 当key不存在,才存入key-value对
127.0.0.1:6379> setnx k1 v300
(integer) 0
127.0.0.1:6379> setnx k3 v300
(integer) 1

# 自增自减
127.0.0.1:6379> set k4 500
OK
127.0.0.1:6379> incr k4
(integer) 501
127.0.0.1:6379> get k4
"501"
127.0.0.1:6379> decr k4
(integer) 500


127.0.0.1:6379> incrby k4 10
(integer) 510
127.0.0.1:6379> decrby k4 20
(integer) 490

Redis的incr是原子性操作,java中不是原子性操作


其他命令:

  • 设置多个键值对:mset k1 v1 k2 v2...
  • 获取多个value:mget k1 k2 ...
  • msetnx k1 v1 k2 v2 k3 v3:原子操作,要么全部成功,要么全部失败
  • getrange key start_index end_index:get范围内的值,索引从0开始
  • setrange key startindex val:将startindex位置上的值用val替代
  • setex key time value:设置过期时间,同时设置值
  • getset key value:返回旧值,同时设置新值
127.0.0.1:6379> flushdb
OK

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

//msetnx要么全部成功,要么全部失败
127.0.0.1:6379> msetnx k11 v11 k12 v12 k1 v11
(integer) 0
127.0.0.1:6379> msetnx k11 v11 k12 v12 k13 v13
(integer) 1
127.0.0.1:6379> keys *
1) "k1"
2) "k3"
3) "k12"
4) "k13"
5) "k2"
6) "k11"
    
    
127.0.0.1:6379> set name lucymary
OK
127.0.0.1:6379> getrange name 0 3
"lucy"
127.0.0.1:6379> setrange name 3 abc
(integer) 8
127.0.0.1:6379> get name
"lucabcry"
    
//设置定时器    
127.0.0.1:6379> setex age 10 value30
OK
127.0.0.1:6379> ttl age
(integer) 4
127.0.0.1:6379> ttl age
(integer) -2
    
//给key设置新值    
127.0.0.1:6379> getset name jack
"lucabcry"
127.0.0.1:6379> get name
"jack"

1.2 String数据结构

String的数据结构是简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内部结构实现类似于Java的ArrayList,采用预分配冗余空间的方法来减少内存的频繁分配。

在这里插入图片描述

2. List列表

单键多值
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
在这里插入图片描述

2.1 常用命令

  • lpush/rpush key value value...:从左或者右插入一个或者多个值(头插与尾插)

  • lpop/rpop key :从左或者右吐出一个或者多个值(值在键在,值都没,键没)

  • rpoplpush key1 key2: 从key1列表右边吐出一个值,插入到key2的左边

  • lrange key start stop 按照索引下标获取元素(从左到右)

  • lrange key 0 -1: 获取所有值

  • lindex key index 按照索引下标获得元素

  • llen key 获取列表长度

  • linsert key before/after value newvalue 在value的前面插入一个新值

  • lrem key n value 从左边删除n个value值

  • lset key index value 在列表key中的下标index中修改值value

127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"

127.0.0.1:6379> rpush k2 v1 v2 v3
(integer) 3
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v2"
3) "v3"

127.0.0.1:6379> lpop k1
"v3"
127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> rpush k2 v11 v12 v13
(integer) 3
127.0.0.1:6379> rpoplpush k1 k2
"v1"
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v11"
3) "v12"
4) "v13"

//索引取值
127.0.0.1:6379> lindex k2
(error) ERR wrong number of arguments for 'lindex' command
127.0.0.1:6379> lindex k2 0
"v1"
127.0.0.1:6379> lindex k2 2
"v12"
    
//获取长度    
127.0.0.1:6379> llen k2
(integer) 4

//指定位置插入值    
127.0.0.1:6379> linsert k2 before "v11" "newv11"
(integer) 5
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "v12"
5) "v13"
127.0.0.1:6379> linsert k2 before "v12" "newv11"
(integer) 6
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "newv11"
5) "v12"
6) "v13"
127.0.0.1:6379> linsert k2 before "v13" "newv11"
(integer) 7
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "newv11"
5) "v12"
6) "newv11"
7) "v13"
    
//删除指定值,且可以指定个数    
127.0.0.1:6379> lrem k2 2 "newv11"
(integer) 2
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v11"
3) "v12"
4) "newv11"
5) "v13"
    
//指定位置替换值    
127.0.0.1:6379> lset k2 1 newnew
OK
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newnew"
3) "v12"
4) "newv11"
5) "v13"

2.2 数据结构

在这里插入图片描述

3. Set集合

Set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动去重的,当你需要存储一个列表数据,又不希望出现重复数据时,Set是一个很好的选择,并且Set提供了判断某个成员是否在一个Set集合内的重要接口,这个也是list所不能提供的。
Redis的Set是String类型的无序集合。它的底层是一个value为null的hash表,所以添加、删除、查找的复杂度都是O(1)

3.1 常用命令

  • sadd key value value... 将一个或者多个member元素加入集合key中,已经存在的member元素被忽略
  • smembers key 取出该集合的所有值
  • sismember key value 判断该集合key是否含有该值,有1,没有0
  • scard key 返回该集合的元素个数
  • srem key value value 删除集合中的某个元素
  • spop key 随机从集合中取出一个元素
  • srandmember key n 随即从该集合中取出n个值,不会从集合中删除
  • smove <一个集合a><一个集合b>value 将一个集合a的某个value移动到另一个集合b
  • sinter key1 key2 返回两个集合的交集元素
  • sunion key1 key2 返回两个集合的并集元素
  • sdiff key1 key2 返回两个集合的差集元素(key1有的,key2没有)
127.0.0.1:6379> sadd k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> smembers k1
1) "v2"
2) "v3"
3) "v1"

//判断set中是否有值
127.0.0.1:6379> sismember k1 v1
(integer) 1
127.0.0.1:6379> sismember k1 v4
(integer) 0

//返回集合中元素个数
127.0.0.1:6379> scard k1
(integer) 3

//删除元素
127.0.0.1:6379> srem k1 v1 v2
(integer) 2
127.0.0.1:6379> smembers k1
1) "v3"
127.0.0.1:6379> sadd k2 v1 v2 v3 v4
(integer) 4
//随机删除元素
127.0.0.1:6379> spop k2
"v1"
127.0.0.1:6379> spop k2
"v4"
127.0.0.1:6379> spop k2
"v3"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd k2 v1 v2 v3 v4
(integer) 4
127.0.0.1:6379> srandmember k2 2    //随机取值
1) "v2"
2) "v3"
127.0.0.1:6379> srandmember k2 2
1) "v1"
2) "v3"
127.0.0.1:6379> sadd k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> sadd k2 v3 v4 v5
(integer) 3
    
//将k1中的v3移入到k2中    
127.0.0.1:6379> smove k1 k2 v3
(integer) 1
127.0.0.1:6379> smembers k1
1) "v2"
2) "v1"
127.0.0.1:6379> smembers k2
1) "v5"
2) "v3"
3) "v4"
    
127.0.0.1:6379>  sadd k3 v3 v4 v5 v7
(integer) 4
127.0.0.1:6379> sinter k2 k3   //交集
1) "v5"
2) "v3"
3) "v4"
127.0.0.1:6379> sunion k2 k3  //并集
1) "v7"
2) "v3"
3) "v4"
4) "v5"
127.0.0.1:6379> sdiff k3 k2  //差集
1) "v7"

3.2 数据类型

Set数据结构是dict字典,字典是用哈希表实现的
Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。
Redis的Set结构也是一样的,它的内部也使用hash结构,所有的value都指向同一个内部值

4. Hash哈希

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

4.1 常用命令

  • hset key field value: 给key集合中的filed键赋值value
  • hget key1 field :集合field取出value
  • hmset key1 field1 value1 field2 value2 :批量设置hash的值
  • hexists key1 field: 查看哈希表key中,给定域field是否存在
  • hkeys key :列出该hash集合的所有field
  • hvals key :列出该hash集合的所有value
  • hincrby key field increment: 为哈希表key中的域field的值加上增量1 -1
  • hsetnx key field value :将哈希表key中的域field的值设置为value,当且仅当域field不存在

在这里插入图片描述

127.0.0.1:6379> hset user:1001 id 1   //插入数据:键 域 值
(integer) 1
127.0.0.1:6379> hset user:1001 name zhangsan
(integer) 1
127.0.0.1:6379> hget user:1001 id
"1"
127.0.0.1:6379> hget user:1001 name
"zhangsan"
    
//一次性插入    
127.0.0.1:6379> hmset user:1002 id 2 name lisi age 30
OK
    
//判断是否存在域    
127.0.0.1:6379> hexists user:1002 id
(integer) 1
127.0.0.1:6379> hexists user:1002 gender
(integer) 0
    
//获取所有域    
127.0.0.1:6379> hkeys user:1002
1) "id"
2) "name"
3) "age"
    
//获取所有值    
127.0.0.1:6379> hvals user:1002
1) "2"
2) "lisi"
3) "30"
    
    
127.0.0.1:6379> hincrby user:1002 age 2
(integer) 32
127.0.0.1:6379> hsetnx user:1002 age 40
(integer) 0
127.0.0.1:6379> hsetnx user:1002 gender 1
(integer) 1

4.2 数据结果

hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。

5. Zset有序集合

Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了
因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。
访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。

5.1 常用命令

  • zadd key score1 value1 score2 value2 :将一个或多个member元素及其score值加入到有序key中
  • zrange key start stop (withscores) :返回有序集key,下标在start与stop之间的元素,带withscores,可以让分数一起和值返回到结果集。
  • zrangebyscore key min max(withscores): 返回有序集key,所有score值介于min和max之间(包括等于min或max)的成员。有序集成员按score的值递增次序排列
  • zrevrangebyscore key max min (withscores):同上,改为从大到小排列
  • zincrby key increment value :为元素的score加上增量
  • zrem key value :删除该集合下,指定值的元素
  • zcount key min max :统计该集合,分数区间内的元素个数
  • zrank key value :返回该值在集合中的排名,从0开始
127.0.0.1:6379> zadd topn 200 java 300 c++ 400 mysql 500 php
(integer) 4
127.0.0.1:6379> zrange topn 0 -1
1) "java"
2) "c++"
3) "mysql"
4) "php"
127.0.0.1:6379> zrange topn 0 -1 withscores
1) "java"
2) "200"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "php"
8) "500"


127.0.0.1:6379> zrangebyscore topn 300 500
1) "c++"
2) "mysql"
3) "php"
127.0.0.1:6379> zrangebyscore topn 300 500 withscores
1) "c++"
2) "300"
3) "mysql"
4) "400"
5) "php"
6) "500"
    

127.0.0.1:6379> zrevrangebyscore topn 500 300
1) "php"
2) "mysql"
3) "c++"
    
127.0.0.1:6379> zincrby topn 50 java
"250"
    
127.0.0.1:6379> zcount topn 200 300
(integer) 2
    
    
127.0.0.1:6379> zrank topn java
(integer) 0
127.0.0.1:6379> zrank topn mysql
(integer) 2
127.0.0.1:6379> zrange topn 0 -1 withscores
1) "java"
2) "250"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "php"
8) "500"

5.2 数据结构

SortedSet(zset)是Redis提供的一个非常特别的数据结构,一方面它等价于Java的数据结构Map<String, Double>,可以给每一个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。

zset底层使用了两个数据结构:
(1)hash。hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
(2)跳跃表。跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。

  • 5
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zdb呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值