redis学习-value数据结构

1、概述

redis是Remote Dictionary Service的简称,也是远程字典服务。

redis是内存型数据库,KV型数据库,数据结构数据库。通过key操作value,value支持多种类型string、list、hash、set、zset等。

2、安装启动

安装

bash 复制代码
下载源码:比如redis-7.0.15
cd redis
make
make install

# 默认安装在/usr/local/bin
# redis-server 是服务端程序
# redis-cli 是客户端程序

启动redis

配置文件redis.conf在源码目录有,可以拷贝到自定义目录,启动时指定目录即可,默认使用端口6379。

bash 复制代码
# 启动redis
redis-server

# 使用配置文件启动redis
redis-server ./redis-data/redis.conf

启动客户端,redis-cli是redis提供的客户端命令行工具,可以通过命令操作redis数据库了

bash 复制代码
# 服务器和客户端在一个机器上
redis-cli

# -h 指定要连接redis节点的ip地址
# -p 指定要连接redis节点的端口,默认6379
# -a 指定redis的访问密码
redis-cli -h 127.0.0.1 -p 6379 -a XXXX

3、数据类型及其存储方式

string:是一个安全的二进制字符串,安全是指以长度区分字符串

list:插入有序的,双端列表

hash:对顺序不关注,field是唯一的

set:对顺序不关注,里面的值都是唯一的

zset:对顺序是关注的,里面的值是唯一的,根据member来确定唯一,根据score来确定有序。

3.0、key的设计

对于单个功能的单个key,使用有意义的名字

SET key value

对于相同功能的多个key,使用有意义字段并用冒号分隔,推荐冒号分隔(当然也可以使用其他分隔符),因为很多开源项目或工具使用冒号分隔的,是大家约定俗成的规定。

SET role:10001 '{["name"]:"张三",["sex"]:"male",["age"]:30}'

3.1、string字符串

扩容机制:字符串长度小于1M时,加倍扩容;超过1M时,每次只多扩1M,字符串最大长度512M

基础命令

# 设置key的value值
SET key val

# 获取key的value
GET key

# 执行原子加一的操作(value必须整数,否则会报错)
INCR key

# 执行原子加一个整数的操作(value必须整数,否则会报错)
INCRBY key increment

# 执行原子减一的操作
DECR key

# 执行原子减一个整数的操作
DECRBY key decrement

# 如果key不存在,这种情况下等同SET命令,当key存在时,什么也不做,只有当key不存在时,才设置成功
SETNX key value

# 删除key val键值对
DEL key

# 设置或清空key的value(字符串)在offset处的bit值
# 动态字符串 能够节约内存
SETBIT key offset value

# 返回key对应的string在offset处的bit值
GETBIT key offset

# 统计字符串被设置为1的bit数
BITCOUNT key

应用场景举例:

场景1:对象存储

将某些json字符串,保存到redis,前提条件json字符串极少修改,如果要经常修改可考虑hash数据结构。

SET role:10001 '{["name"]:"张三",["sex"]:"male",["age"]:30}'
SET role:10002 '{["name"]:"李四",["sex"]:"male",["age"]:30}'
# 极少修改,对象属性字段很少改变的时候
GET role:10001

场景2:累加器

# 统计阅读数 累加1
incr reads

# 累计加100
incrby reads 100

场景3:位运算

# 月签到功能 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

自测

3.2、list双端列表

双向列表实现,列表首尾操作(删除和增加)时间复杂度o(1),查找中间元素时间复杂度为o(n)

基础命令

# 从队列的左侧入队一个或多个元素
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没有去重功能
LREM key count value

# 它是RPOP的阻塞版本,因为这个命令会在给定list无法弹出任何元素的时候,阻塞连接
BRPOP key timeout # 超时时间 + 延时队列

BRPOP命令:拥有移出并获取list右边最后一个元素,如果列表中没有元素,则卡住命令知道等到超时或发现可弹出元素为止。比如:A机器调用brpop等待弹出元素,B机器调用lpush插入数据,此时A机器brpop会弹出对应元素。

应用场景举例:

场景1:获取固定窗口记录

# 在某些业务场景下,需要获取固定数量的记录;比如获取最近50条记录;这些记录需要按照插入的先
后顺序返回;
lpush says '第一条评论'
lpush says '第二条评论'
lpush says '第三条评论'
lpush says '第四条评论'
lpush says '第五条评论'
lpush says '第六条评论'
lpush says '第七条评论'


# 裁剪最近5条记录 战绩 近50条
ltrim says 0 4
lrange says 0 -1

自测:

3.3、hash

散列表,在很多高级语言当中包含这种数据结构,C++unordered_map通过key快速索引value。

基础命令

bash 复制代码
# 获取key对应hash中的 field对应的值
HGET key field

# 设置key对应hash中的封field对应的值
HSET key field

# 设置多个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

# 获取key的所有字段
HGETALL key

应用场景举例:

场景1:购物车

bash 复制代码
# 将用户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 40003

自测

3.4、set集合

集合,用来存储唯一性字段,不要求有序。集合可以用来计算交集、并集等业务场景。

基础命令

bash 复制代码
# 添加一个或多个指定的member元素到集合的key中
SADD key member [member ...]

# 计算集合元素个数
SCARD key

# SMEMBERS key 返回集合中的member
SMEMBERS key

# 返回成员member 是否是存储的集合key的成员
SISMEMBER key member

# 随机返回key集合中的一个或多个元素,不删除这些元素
SRANDMEMBER key [count]

# 从存储在key的集合中移除并返回一个或多个随机元素
SPOP key [count]

# 返回一个集合与给定集合 差集的元素
SDIFF key [key ...]

# 返回一个集合与给定集合的交集
SINTER key [key ...]

# 返回给定的多个集合的并集的所有成员
SUNION key [key ...]

应用场景举例

场景1:抽奖

bash 复制代码
# 添加抽奖用户
sadd Award:1 10001 10002 10003 10004 10005 10006
sadd Award:1 10009

# 查看所有抽奖用户
smembers Award:1

# 抽取多名幸运用户
srandmember Award:1 10

场景2:共同关注

bash 复制代码
sadd follow:A aa bb cc dd ee
sadd follow:C aa 22 cc 11 ee
sinter follow:A follow:C

场景3:推荐好友

bash 复制代码
sadd follow:A aa bb cc dd ee
sadd follow:C aa 22 cc 11 ee
sdiff follow:A follow:C

自测:

3.5、zset

有序集合,用来实现排行榜,它是一个有序唯一。

基础命令

bash 复制代码
# 添加到键为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]

应用场景举例

bash 复制代码
# 点击新闻:
zincrby hot:20230612 1 10001
zincrby hot:20230612 1 10002
zincrby hot:20230612 1 10003
zincrby hot:20230612 1 10004
zincrby hot:20230612 1 10005
zincrby hot:20230612 1 10006
zincrby hot:20230612 1 10007
zincrby hot:20230612 1 10008
zincrby hot:20230612 1 10009
zincrby hot:20230612 1 10010

# 获取排行榜:
zrevrange hot:20230612 0 9 withscores

自测

4、总结

通常是组合使用的方式,实现业务需求,比如:hash + list组合等方式。

学习链接:https://github.com/0voice

相关推荐
杂货铺的小掌柜9 分钟前
spring mvc源码学习笔记之十
学习·spring·mvc
背太阳的牧羊人1 小时前
使用 SQLite3 的基本操作步骤
数据库·sqlite
从后端到QT1 小时前
Android NDK开发入门2之适应idm环境
前端·javascript·数据库
背太阳的牧羊人1 小时前
使用 SQL 和表格数据进行问答和 RAG(6)—将指定目录下的 CSV 或 Excel 文件导入 SQLite 数据库
数据库·sql·langchain·sqlite·excel
studyForMokey1 小时前
【Android项目学习】2.抖音二级评论
android·学习
笑小枫1 小时前
SpringBoot 使用 Cache 集成 Redis做缓存保姆教程
spring boot·redis·缓存
咬光空气1 小时前
Qt 5.14.2 学习记录 —— 오 信号与槽机制(2)
开发语言·qt·学习
唐梓航-求职中1 小时前
缓存-Redis-常见问题-缓存击穿-永不过期+逻辑过期(全面 易理解)
数据库·redis·缓存
潜洋2 小时前
Spring Boot教程之五十二:CrudRepository 和 JpaRepository 之间的区别
java·大数据·数据库·spring boot
潘多编程2 小时前
Spring Boot微服务中进行数据库连接池的优化?
数据库·spring boot·微服务