redis数据库学习一

一、redis数据库介绍

1.介绍

redis数据在内存中,读取速度快,但易丢失,是key-value型数据库,类比于字典,通过key去操作value,mysql数据在磁盘中读取速度慢。key-value一一对应,请求回应模式,使用TCP与redis数据通信,对于发送的请求redis必须做出回应。

2.1安装redis

git clone https://gitee.com/mirrors/redis.git -b 6 .2
cd redis
make
make test
make install
# 默认安装在 /usr/local/bin
# redis-server 是服务端程序
# redis-cli 是客户端程序
2.2启动redis
mkdir redis-data
# redis 文件夹下 redis.conf 拷贝到 redis-data
# 修改 redis.conf
# requirepass 修改密码 123456
# daemonize yes
cd redis-data
redis-server redis.conf
# 通过 redis-cli 访问 redis-server
redis-cli -h 127 .0.0.1 -a 123456

3. 五种基本类型

4.redis简单操作

4.1 string操作
4.2 list操作
list为key,对应的value是一个双向循环list,返回value使用lrange,返回全部元素索引为(0,-1)
4.3 hash操作
4.4 set操作
set为一个集合,集合中的元素不能重复
4.5 zset操作:
zset是一个有序的集合,value格式是(c1, m1),c1是序号scores,一个m1出现新的c1会覆盖以前的。
redis的key-value结构是一个散列表,value有不同的结构
安全的二进制字符串指:在一段字符串前有字符串长度,以长度结束的字符串,不以\0结束的字符串。
具有唯一性的数据结构可以实现数据去重。
redis中value编码
redis内存数据库:
1.到底是要运行速度快,还是要存储效率高;
2.数据量少的时候,存储效率高为主;
3.数据量多的时候,运行速度快为主;

二、基本操作

1.string类型

字符数组类型, 该字符串是动态字符串raw,当字符串长度小于1M时,加倍扩容;超过1M每次之扩容1M;最大长度为512M;

注意:redis字符串是二进制安全字符串;可以存储图片,二进制协议等二进制数据;

1.1 基础命令
# 设置 key value
SET key val
# 获取 key value
GET key
# 执行原子加一的操作
INCR key
# 执行原子加一个整数的操作
INCRBY key increment
# 执行原子减一的操作
DECR key
# 执行原子减一个整数的操作
DECRBY key decrement
# 如果 key 不存在,这种情况下等同 SET 命令。 当 key 存在时,什么也不做
# set Not eXist ok 这个命令是否执行了 0,1 是不是操作结果是不是成功
SETNX key value
# 删除 key val 键值对
DEL key
# 设置或者清空 key value( 字符串 ) offset 处的 bit 值。 setbit embstr raw int
# 动态字符串 能够节约内存
SETBIT key offset value
# 返回 key 对应的 string offset 处的 bit
GETBIT key offset
# 统计字符串被设置为 1 bit .
BITCOUNT key
1.2 存储结构

字符串长度小于等于20且能转成整数,则使用int存储;

字符串长度小于等于40,则使用embstr存储;

字符串长度大于44,则使用raw存储;

1.3 应用

对象存储:

用于极少修改的对象,对象属性字段很少改变的时候,类似于这种:

累加器:

# 统计阅读数 累计加 1
incr reads
# 累计加 100
incrby reads 100
分布式锁:
# 加锁 加锁 和 解析 redis 实现是 非公平锁 ectd zk 用来实现公平锁
# 阻塞等待 阻塞连接的方式
# 介绍简单的原理: 事务
setnx lock 1 # 不存在才能设置 定义加锁行为 占用锁
setnx lock uuid # expire 30 过期
set lock uuid nx ex 30
# 释放锁
del lock
if (get(lock) == uuid)
del(lock);
位运算:
# 月签到功能 10001 用户 id 202106 2021 6 月份的签到 6 月份的第 1
setbit sign:10001:202106 1 1
# 计算 2021 6 月份 的签到情况
bitcount sign:10001:202106
# 获取 2021 6 月份 第二天的签到情况 1 已签到 0 没有签到
getbit sign:10001:202106 2

2. list类型

双向链表结构,首尾查找时间复杂度为O(1),中间位置的查找时间复杂度为O(n);

列表中数据压缩依据:

元素长度小于48,不压缩;

元素压缩前后长度差不超过 8,不压缩;

2.1 基础命令
# 从队列的左侧入队一个或多个元素
LPUSH key value [value ...]
# 从队列的左侧弹出一个元素
LPOP key
# 从队列的右侧入队一个或多个元素
RPUSH key value [value ...]
# 从队列的右侧弹出一个元素
RPOP key
# 返回从队列的 start end 之间的元素 0, 1 2 负索引
LRANGE key start end
# 从存于 key 的列表里移除前 count 次出现的值为 value 的元素
# list 没有去重功能 hash set zset
LREM key count value
# 它是 RPOP 的阻塞版本,因为这个命令会在给定 list 无法弹出任何元素的时候阻塞连接
BRPOP key timeout # 超时时间 + 延时队列
redis为请求回应机制,当服务器发送请求,redis必须做出回应,当list为空时,brpop list会发生阻塞,redis不会产生回应,只有当list中有数据时,brpop list会立即返回。
s1发送brpop list 0阻塞,s2 push value,s1收到返回。
2.2 存储结构
/* Minimum ziplist size in bytes for attempting compression. */
#define MIN_COMPRESS_BYTES 48
/* quicklistNode is a 32 byte struct describing a ziplist for a quicklist.
* We use bit fields keep the quicklistNode at 32 bytes.
* count: 16 bits, max 65536 (max zl bytes is 65k, so max count actually <
32k).
* encoding: 2 bits, RAW=1, LZF=2.
* container: 2 bits, NONE=1, ZIPLIST=2.
* recompress: 1 bit, bool, true if node is temporary decompressed for
usage.
* attempted_compress: 1 bit, boolean, used for verifying during testing.
* extra: 10 bits, free for future use; pads out the remainder of 32 bits */
typedef struct quicklistNode {
struct quicklistNode * prev ;
struct quicklistNode * next ;
unsigned char * zl ;
unsigned int sz ; /* ziplist size in bytes */
unsigned int count : 16 ; /* count of items in ziplist */
unsigned int encoding : 2 ; /* RAW==1 or LZF==2 */
unsigned int container : 2 ; /* NONE==1 or ZIPLIST==2 */
unsigned int recompress : 1 ; /* was this node previous compressed? */
unsigned int attempted_compress : 1 ; /* node can't compress; too small
*/
unsigned int extra : 10 ; /* more bits to steal for future usage */
} quicklistNode ;
typedef struct quicklist {
quicklistNode * head ;
quicklistNode * tail ;
unsigned long count ; /* total count of all entries in all
ziplists */
unsigned long len ; /* number of quicklistNodes */
int fill : QL_FILL_BITS ; /* fill factor for individual
nodes */
unsigned int compress : QL_COMP_BITS ; /* depth of end nodes not to
compress;0=off */
unsigned int bookmark_count : QL_BM_BITS ;
quicklistBookmark bookmarks [];
} quicklist ;
2.3 应用
栈(先进后出)
LPUSH + LPOP
# 或者
RPUSH + RPOP
队列(先进先出)
LPUSH + RPOP
# 或者
RPUSH + LPOP
阻塞队列(blocking queue)
LPUSH + BRPOP
# 或者
RPUSH + BLPOP
异步消息队列
操作与队列一样,但是在不同系统间;生成者和消费者;
获取固定窗口记录
#往队列中push数据
lpush list value
#从左开始裁剪前50个数据
ltrim list 0 49
lrange list 0 -1

3.hash

散列表,在很多高级语言当中包含这种数据结构; c++ unordered_map 通过 key 快速索引
value ;一般存储属性经常改变的对象。
3.1 基础命令
# 获取 key 对应 hash 中的 field 对应的值
HGET key field
# 设置 key 对应 hash 中的 field 对应的值
HSET key field value
# 设置多个 hash 键值对
HMSET key field1 value1 field2 value2 ... fieldn valuen
# 获取多个 field 的值
HMGET key field1 field2 ... fieldn
# key 对应 hash 中的 field 对应的值加一个整数值
HINCRBY key field increment
# 获取 key 对应的 hash 有多少个键值对
HLEN key
# 删除 key 对应的 hash 的键值对,该键为 field
HDEL key field
3.2 存储结构

节点数量大于512(hash-max-ziplist-entries)或所有字符串长度大于64(hash-max-ziplist-value),则使用dict实现;

节点数量小于等于512且有一个字符串长度小于64,则使用ziplist实现;

3.3 应用

存储对象

hmset hash:10001 name mark age 18 sex male
# string 比较
set hash:10001 '{["name"]:"mark",["sex"]:"male",["age"]:18}'
# 假设现在修改 mark 的年龄为 19
# hash
hset hash:10001 age 19
# string:
get hash:10001
# 将得到的字符串调用 json 解密,取出字段,修改 age
# 再调用 json 加密
set hash:10001 '{["name"]:"mark",["sex"]:"male",["age"]:19}'

购物车

# 将用户 id 作为 key
# 商品 id 作为 field
# 商品数量作为 value
# 注意:这些物品是按照我们添加顺序来显示的;
# 添加商品:
hmset MyCart:10001 40001 1 cost 5099 desc " 戴尔笔记本 14-3400"
lpush MyItem:10001 40001
# 增加数量:
hincrby MyCart:10001 40001 1
hincrby MyCart:10001 40001 -1 // 减少数量 1
# 显示所有物品数量:
hlen MyCart:10001
# 删除商品:
hdel MyCart:10001 40001
lrem MyItem:10001 1 40001
# 获取所有物品:
lrange MyItem:10001
# 40001 40002 40003
hget MyCart:10001 40001
hget MyCart:10001 40002
hget MyCart:10001 4000s et

4.set

4.1 基础命令
# 添加一个或多个指定的 member 元素到集合的 key
SADD key member [member ...]
# 计算集合元素个数
SCARD key
# SMEMBERS key
SMEMBERS key
# 返回成员 member 是否是存储的集合 key 的成员
SISMEMBER key member
# 随机返回 key 集合中的一个或者多个元素,不删除这些元素
SRANDMEMBER key [count]
# 从存储在 key 的集合中移除并返回一个或多个随机元素
SPOP key [count]
# 返回一个集合与给定集合的差集的元素
SDIFF key [key ...]
# 返回指定所有的集合的成员的交集
SINTER key [key ...]
# 返回给定的多个集合的并集中的所有成员
SUNION key [key ...]
4.2 存储结构
元素都为整数且节点数量小于等于 512 set-max-intset-entries ),则使用整数数组存储;
元素当中有一个不是整数或者节点数量大于 512 ,则使用字典存储;
4.3 应用

抽奖

# 添加抽奖用户
sadd Award:1 10001 10002 10003 10004 10005 10006
sadd Award:1 10009
# 查看所有抽奖用户
smembers Award:1
# 抽取多名幸运用户
srandmember Award:1 10
# 如果抽取一等奖 1 名,二等奖 2 名,三等奖 3 名,该如何操作?
srandmember Award:1 
srandmember Award:1 2
srandmember Award:1 3
共同关注
sadd follow:A mark king darren mole vico
sadd follow:C mark king darren
sinter follow:A follow:C
推荐好友
sadd follow:A mark king darren mole vico
sadd follow:C mark king darren
# C 可能认识的人:
sdiff follow:A follow:C

5. zset

有序集合;用来实现排行榜;值是有序的且是唯一的;
5.1 基础命令
# 添加到键为 key 有序集合( sorted set )里面
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
# 从键为 key 有序集合中删除 member 的键值对
ZREM key member [member ...]
# 返回有序集 key 中,成员 member score
ZSCORE key member
# 为有序集 key 的成员 member score 值加上增量 increment
ZINCRBY key increment member
# 返回 key 的有序集元素个数
ZCARD key
# 返回有序集 key 中成员 member 的排名
ZRANK key member
# 返回存储在有序集合 key 中的指定范围的元素 order by id limit 1,100
ZRANGE key start stop [WITHSCORES]
# 返回有序集 key 中,指定区间内的成员 ( 逆序 )
ZREVRANGE key start stop [WITHSCORES]
5.2 存储结构
节点数量大于 128 或者有一个字符串长度大于 64 ,则使用跳表( skiplist );
节点数量小于等于 128 zset-max-ziplist-entries )且所有字符串长度小于等于 64 zset-max
ziplist-value ),则使用 ziplist 存储;
数据少的时候,节省空间; $O(n)$
数量多的时候,访问性能; $O(1)$ or $O(log_{2}{n})$
5.3 应用
百度热搜
zincrby hot:20240712 1 100
zincrby hot:20240712 1 101
zincrby hot:20240712 1 102
zincrby hot:20240712 1 103
zincrby hot:20240712 1 104
zincrby hot:20240712 1 105
zrevrange hot:20240712 0 5
延时队列
将消息序列化成一个字符串作为 zset member ;这个消息的到期处理时间作为 score ,然后用
多个线程轮询 zset 获取到期的任务进行处理。

 分享一个学习链接,有需要的同学可以看一下:

https://xxetb.xetslk.com/s/3yNycZ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值