Redis | 十大数据类型

news/2025/2/9 3:17:50 标签: redis, 数据库, 数据类型

文章目录

十大数据类型概述

在这里插入图片描述

在这里插入图片描述


key操作命令

keys * // 查看当前库所有的key

exists key // 判断某个key是否存在,存在返回1不存在返回0,若查询多个key,返回存在的key的数量

type key // 查看你的key是什么类型

del key // 删除指定的key数据,是原子的删除,只有删除成功了才会返回删除结果,如果是删除大key用del会将后面的操作都阻塞

unlink key // 非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在后续异步中操作。删除大key不会阻塞,它会在后台异步删除数据。

ttl key // 查看还有多少秒过期,-1表示永不过期,-2表示已过期

expire key seconds// 为给定的key设置过期时间几秒

move key dbindex[0-15] //  将当前数据库的key移动到给定的数据库当中,一个redis默认带着16个数据库

select dbindex // 切换数据库[0-15],默认为0

dbsize // 查看当前数据库key的数量

flushdb // 清空当前库

flushall // 清空全部库

数据类型命令及落地运用

  • 官网命令大全网址:
    • https://redis.io/commands/
    • http://www.redis.cn/commands.html
  • 命令不区分大小写,而 key 是区分大小写的。
  • 永远的帮助命令:help @类型

redisString_48">redis字符串(String)

  • 官网地址:https://redis.io/docs/data-types/strings/
  • keyvalue
  • stringredis 最基本的类型,一个 key 对应一个 value
  • string 类型是二进制安全的,意思是 redisstring 可以包含任何数据,比如 jpg 图片或者序列化的对象。【如何理解二进制安全?二进制安全表示数据在存储和传输时不会被修改或解释,redisstring 类型的数据视为字节序列,不关心其内容。因此,string 类型可以存储任何数据,包括文本、图片、序列化对象等。】
  • string 类型是 redis 最基本的数据类型,一个 redis 中字符串 value 最多可以是 512M
set key value [NX|XX [GET] [EX seconds|PX milliseconds|EXAT unix-time-seconds|PXAT unix-time-milisecondS|KEEPTTL]
  • SET 命令有 EXPXNXXX 以及 KEEPTTL 五个可选参数,其中 KEEPTTL6.0 版本添加的可选参数
  • EX seconds:以秒为单位设置过期时间。
  • PX milliseconds:以毫秒为单位设置过期时间。
  • EXAT timestamp:设置以秒为单位的 UNIX 时间戳所对应的时间为过期时间。
  • PXAT milliseconds-timestamp:设置以毫秒为单位的UNIX时间戳所对应的时间为过期时间。
  • NX:键不存在的时候设置键值。
  • EX:键存在的时候设置键值。
  • KEEPTTL:保留设置前指定键的生存时间。
  • GET:返回指定键原本的值,若键不存在时返回 nil
  • SET 命令使用 EXPXNX 参数,其效果等同于 SETEXPSETEXSETNX 命令。根据官方文档的描述,未来版本中 SETEXPSETEXSETNX 命令可能会被淘汰。
  • EXATPXAT 以及 GETRedis 6.2 新增的可选参数。
set k1 v1xx // 设置k1的值
get k1 // 查看k1的值
set k1 v2 nx // if not exist 如果k1未存在则设置为v2
set k1 v1x xx // if exist 如果k1存在则修改其value为v1x
set k1 v1 get // 先把原先有的k1对应的value输出出来,然后把v1设置为其新值
set k1 v1 ex 10 // 设置k1的值为v1,过期时间为10秒后
ttl k1 // 查看k1所剩的有效时间
set k1 v1 px 8000 // 设置k1的值为v1,过期时间为8000毫秒后
set k1 v1 exat 1697049600 // 用unix时间戳不需要系统底层时间换算,会稍微准一点
  • Unix 时间戳是从 1970 年 1 月 1 日 00:00:00 UTC (称为 Unix 纪元)开始计算的秒数或毫秒数,秒级时间戳是毫秒级时间戳除以 1000 的结果。
  • Golang 如何获得设置指定的 key 过期的 unix 时间戳,单位为秒:
package main

import (
	"fmt"
	"time"
)

func main() {
	// 获取当前时间的 Unix 时间戳(以秒为单位)
	timestamp := time.Now().Unix()
	// 将时间戳转换为字符串并打印
	fmt.Println(fmt.Sprintf("%d", timestamp))
}
set k1 v1 ex 30 // OK
ttl k1 // (integer) 29
set k1 v11 // OK
ttl k1 // (integer) -1
  • 这里的问题是,同一个 key,之前设置了过期时间,但是做了修改,如果没有继续追加时间,它就会默认为永不超时,把以前的过期时间给覆盖了。
set k1 v1 ex 30 // OK
ttl k1 // (integer) 29
set k1 v11 keepttl// OK
ttl k1 // (integer) 13
  • 如果要同时设置 / 获取多个键值呢?MSET key value [key value ....]MGET key [key ....]mset/mget/msetnx
mset k1 v1 k2 v2 k3 v3 // OK
mget k1 k2 k3 // 1) "v1" 2) "v2" 3) "v3"
msetnx k1 v1 k4 v4 // k1存在 k4不存在 (integer) 0 类似于事务的完整性,要么一起成功要么一起失败
get k4 // (nil)
mset k5 v5 k6 v6 // (integer) 1
mget k1 k2 k3 k5 k6 // 1) "v1" 2) "v2" 3) "v3" 4) "v5" 5) "v6"
  • 获取指定区间范围内的值:getrange/setrange
set k1 abcd1234 // OK
getrange k1 0 -1 // "abcd1234" 类似于substring
getrange k1 0 3 // "abcd"
getrange k1 0 4 // "abcd1"
setrange k1 1 xxyy // (integer) 8
get k1 // "axxyy234" 相当于从第1位开始后面用xxyy覆盖对应位置
  • 数值增减:一定要是数据才能进行加减!!!
set k1 100 // OK
get k1 // "100"

// 递增数字:INCR key
incr k1 // (integer) 101
incr k1 // (integer) 102
incr k1 // (integer) 103
incr k1 // (integer) 104

// 增加指定的整数:INCRBY key increment
incrby k1 3 // (intefer) 107
incrby k1 3 // (intefer) 110
incrby k1 3 // (intefer) 113
incrby k1 3 // (intefer) 116
incrby k1 3 // (intefer) 119

// 递减数值:DECR key
decr k1 // (integer) 118
decr k1 // (integer) 117
decr k1 // (integer) 116
decr k1 // (integer) 115

// 减少指定的整数:DECRBY key decrement
decrby k1 5 // (integer) 110
decrby k1 5 // (integer) 105
decrby k1 5 // (integer) 100
decrby k1 5 // (integer) 95
  • 获取字符串长度和内容追加:
// 获取字符串长度:strlen key
set k1 abcd // OK
strlen k1 // (integer) 4

// 字符串内容追加:append key value
append k1 xxxx // (integer) 8
get k1 // "abcdxxxx"
  • 分布式锁:setnx key valuesetex(set with expire)键秒值/setnx(set if not exist)

在这里插入图片描述

  • getset (先 getset):将给定 key 的值设为 value,并返回 key 的旧值( old value )
set k1 v11 // OK
getset k1 haha // "v11"
get k1 // "haha"
set k1 v1 get // "haha"
get k1 // "v1"

redisList_190">redis列表(List)

在这里插入图片描述

  • keyvalue
  • redislist 是简单的字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部(左边)或者尾部(右边)
  • 它的底层实际是个双端链表,最多可以包含 2 32 − 1 2^{32}-1 2321 个元素(4294967295,每个列表超过 40亿 个元素)
lpush list1 1 2 3 4 5 // (integer) 5
rpush list2 11 22 33 44 55 // (integer) 5
type list1 // list
lrange list1 0 -1 // 全部遍历 1) "5" 2) "4" 3) "3" 4) "2" 5) "1"
lrange list1 0 -1 // 全部遍历 1) "11" 2) "22" 3) "33" 4) "44" 5) "55"
// 注意:这里没有 rrange !!!
lpush list1 1 2 3 4 5 // (integer) 5
lpop list1 // "5"
lrange list1 0 -1 // 1) "4" 2) "3" 3) "2" 4) "1"
rpop list1 // "1"
lrange list1 0 -1 // 1) "4" 2) "3" 3) "2"
// lindex 按照索引下标获得元素(从上到下)
lpush list1 1 2 3 4 5 // (integer) 5
lindex list1 0 // "5"
lindex list1 2 // "3"
// llen 获取list列表中元素的个数
lpush list1 1 2 3 4 5 // (integer) 5
llen list1 // (integer) 5
// lrem key 数字N 给定值v1, 删除N个值等于v1的元素
// 从 left 往 right 删除 2 个值等于 v1 的元素,返回值为实际删除的数量
// lrem list3 0值表示删除全部给定的值,0个就是全部值
lpush list3 v1 v1 v1 v2 v3 v3 v4 v5 // (integer) 8
lrange list3 0 -1 // 1) "v5" 2) "v4" 3) "v3" 4) "v3" 5) "v2" 6) "v1" 7) "v1" 8) "v1"
lrem list3 2 v1 // (integer) 2
lrange list3 0 -1 // 1) "v5" 2) "v4" 3) "v3" 4) "v3" 5) "v2" 6) "v1"
// ltrim key 开始index 结束index, 截取指定范围的值后在赋值给key,类似于substring
lpush list1 0 1 2 3 4 5 6 7 8 9 // (integer) 10
lrange list1 0 -1 // 1) "9" 2) "8" 3) "7" 4) "6" 5) "5" 6) "4" 7) "3" 8) "2" 9) "1" 10) "0"
ltrim list1 3 5 // OK
lrange list1 0 -1 // 1) "6" 2) "5" 3) "4"
// rpoplpush 源列表 目的列表, 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
// RPOPLPUSH 这个命令在 Redis 6.2.0 已标注为过期,推荐使用 LMOVE 命令
lpush list1 1 2 2 2 // (integer) 4
lpush list2 11 22 33 44 55 // (integer) 5
rpoplpush list1 list2 // "1"
lrange list1 0 -1 // 1) "2" 2) "2" 3) "2"
lrange list2 0 -1 // 1) "1" 2) "11" 3) "22" 4) "33" 5) "44" 6) "55"

在这里插入图片描述

// lset key index value, 让指定数组集合的小标位置值替换成新值
lpush list1 1 2 2 2 // (integer) 4
lrange list1 0 -1 // 1) "2" 2) "2" 3) "2"
lset list1 1 redis // OK
lrange list1 0 -1 // 1) "2" 2) "redis" 3) "2"
// linsert key before/after 已有值 插入的新值
lpush list1 1 2 2 2 // (integer) 4
lrange list1 0 -1 // 1) "2" 2) "2" 3) "2"
lset list1 1 redis // OK
lrange list1 0 -1 // 1) "2" 2) "redis" 3) "2"
linsert list1 before redis golang // (integer) 4
lrange list1 0 -1 // 1) "2" 2) "golang" 3) "redis" 4) "2"

redisHash_274">redis哈希表(Hash)

  • KV 模式不变,但 V 是一个键值对 map[string]map[interface{}]interface{}
  • redis hash 是一个 string 类型的 field(字段)和 value(值)的映射表,hash 特别适合用于存储对象
  • redis 中每个 hash 可以存储 2 32 − 1 2^{32}-1 2321 键值对(40多亿)
hset user:001 id 11 name z3 age 21 // (integer) 3
hget user:001 id // "11"
hget user:001 name // "z3"
hmset user:001 id 12 name li4 age 26 // OK
hmget user:001 id name age // 1) "12" 2) "li4" 3) "26"
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4" 5) "age" 6) "26"
hdel user:001 age // (integer) 1
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4"
// hlen 获取某个key内的全部数量
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4"
hlen user:001 // (integer) 2
// hexists key 在key里面的某个值的key
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4"
hexists user:001 name // (integer) 1
hexists user:001 score // (integer) 0
// hkeys key 查询出所有key对应的子key值
// hvals key 查询出所有key对应的子key的value值
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4"
hkeys user:001 // 1) "id" 2) "name"
hvals user:001 // 1) "12" 2) "li4"
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4"
hset user:001 age 26 score 99.5 // (integer) 2
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4" 5) "age" 6) "26" 7) "score" 8) "99.5"
hincrby user:001 age 1 // (integer) 27
hincrby user:001 age 1 // (integer) 28
hincrby user:001 age 2 // (integer) 30
hgetall user:001 // 1) "id: 2) "12" 3) "name" 4) "li4" 5) "age" 6) "30" 7) "score" 8) "99.5"
hincrbyfloat user:001 score 0.5 // "100"
hincrbyfloat user:001 score 0.5 // "100.5"
hincrbyfloat user:001 score 0.5 // "101"
// hsetnx,不存在赋值,存在了无效
hsetnx user:001 email redis@163.com // (integer) 1
hsetnx user:001 email redis@163.com // (integer) 0

redisSet_330">redis集合(Set)

  • 单值多 value,且 无重复【和 list 的区别】
  • redissetstring 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,集合对象的编码可以是 intset 或者 hashtable
  • redisset 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)
  • 集合中最大的成员数为 2 32 − 1 2^{32}-1 2321 (4294967295,每个集合可存储 40多亿 个成员)
// SADD key member [member ...] 添加元素,可以多次向同一个key中设置不同值,不会覆盖之前的值
sadd set1 1 1 1 2 2 2 2 3 3 4 4 4 4 4 4 4 4 5 // (integer) 5
// SMEMBERS key 遍历集合中的所有元素
smembers set1 // 1) "1" 2) "2" 3) "3" 4) "4" 5) "5"
// SISMEMBER key member 判断元素是否在集合中
sismember set1 6 // (integer) 0
sismember set1 1 // (integer) 1
sismember set1 5 // (integer) 1
// SREM key member [member ...] 删除元素 删除成功返回1失败返回0
srem set1 7 // (integer) 0
srem set1 1 // (integer) 1
smembers set1 // 1) "2" 2) "3" 3) "4" 4) "5"
// scard 获取集合里面的元素个数
scard set1 // (integer) 4
sadd set1 1 1 1 2 2 2 2 3 3 4 4 4 4 4 4 4 4 5 6 6 7 8 8 8 // (integer) 8
smembers set1 // 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "6" 7) "7" 8) "8"
// SRANDMEMBER key [数字] 从集合中随机展现[设置的数字个数]元素,元素不删除
srandmember set1 1 // "3"
srandmember set1 3 // 1) "7" 2) "2" 3) "6"
smembers set1 // 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "6" 7) "7" 8) "8"
// SPOP key [数字] 从集合中随机[弹出]一个元素,出一个删除一个
spop set1 1 // "8"
spop set1 1 // "2"
spop set1 2 // 1) "6" 2) "4"
smembers set1 // 1) "1" 2) "3" 3) "5" 4) "7"
smembers set1 // 1) "1" 2) "3" 3) "5" 4) "7"
// smove key1 key2 member 将key1里已存在的某个值member赋给key2
sadd set2 a b c // (integer) 3
smove set1 set2 7 // (integer) 1
smembers set1 // 1) "1" 2) "3" 3) "5"
smembers set2 // 1) "b" 2) "a" 3) "7" 4) "c"
// 集合运算
sadd set1 a b c 1 2 // (integer) 5
sadd set2 1 2 3 a x // (integer) 5
// 集合的差集运算 A - B 属于A但是不属于B的元素构成的集合 SDIFF key [key ...],可以计算多个元素的差集
sdiff set1 set2 // 1) "b" 2) "c"
sdiff set2 set1 // 1) "3" 2) "x"
// 集合的并集运算 A ∪ B 属于A或者属于B的元素构成的集合 SUNION key [key ...]
sunion set1 set2 // 1) "x" 2) "a" 3) "b" 4) "1" 5) "2" 6) "3" 7) "c"
// 集合的交集运算 A ∩ B 属于A同时也属于B的共同拥有的元素构成的集合 SINTER key [key ...]
sinter set1 set2 // 1) "a" 2) "1" 3) "2"

redisZSet__SortedSet_389">redis有序集合(ZSet / SortedSet)

  • Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序,
  • zset的成员是唯一的,但分数(score)却可以重复。
  • zset集合是通过哈希表实现的,所以添加,删除,査找的复杂度都是 O(1)。 集合中最大的成员数为 2^32-1

redisGEO_393">redis地理空间(GEO)

  • Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,包括:
    • 添加地理位置的坐标。
    • 获取地理位置的坐标
    • 计算两个位置之间的距离。
    • 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合

redisHyperLogLog_399">redis基数统计(HyperLogLog)

  • HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定且是很小的。
  • 可以类比电商网站首页,每天访问量是很大的,统计基数(不重复ip对首页的访问数量)
  • 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
  • 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

redisbitmap_404">redis位图(bitmap)

在这里插入图片描述

  • 由0和1状态表现的二进制位的bit数组
  • 每日签到 / 打卡

redisbitfield_408">redis位域(bitfield)

  • 通过bitfield命令可以一次性操作多个比特位域(指的是连续的多个比特位),它会执行一系列操作并返回一个响应数组,这个数组中的元素对应参数列表中的相应操作的执行结果。
  • 说白了就是通过bitfield命令我们可以一次性对多个比特位域进行操作。

redisStream_411">redis流(Stream)

  • Redis Stream 是 Redis 5.0 版本新增加的数据结构。
  • Redis Stream 主要用于消息队列(MQ, Message Queue.
  • Redis 本身是有一个 Redis 发布订阅(pub/sub)来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis宕机等消息就会被丢弃
  • 简单来说发布订阅(pub/sub)可以分发消息,但无法记录历
  • 而 Redis Stream 提供了消息的持久化和主备复制功能,可!让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失

http://www.niftyadmin.cn/n/5845479.html

相关文章

结合源码看Restormer的网络设计

下面是restormer的结构示意图。restormer集合了众多的技术,包括unet结构,1x1卷积和深度卷积,还有nlp中常用的layer norm,attention结构。 OverlapPatchEmbed 第一个结构是OverlapPatchEmbed。这是通过卷积把图像映射到高维空间&…

feign Api接口中注解问题:not annotated with HTTP method type (ex. GET, POST)

Bug Description 在调用Feign api时,出现如下异常: java.lang.IllegalStateException: Method PayFeignSentinelApi#getPayByOrderNo(String) not annotated with HTTPReproduciton Steps 1.启动nacos-pay-provider服务,并启动nacos-pay-c…

Java 的 CopyOnWriteArrayList 和 Collections.synchronizedList 有什么区别?分别有什么优缺点?

参考答案拆解 1. 核心概念对比 特性CopyOnWriteArrayListCollections.synchronizedList实现机制写时复制(Copy-On-Write)方法级同步(synchronized块)锁粒度写操作使用ReentrantLock,读操作无锁所有操作使用对象级锁&…

Elasticsearch:向量搜索的快速介绍

作者:来自 Elastic Valentin Crettaz 本文是三篇系列文章中的第一篇,将深入探讨向量搜索(也称为语义搜索)的复杂性,以及它在 Elasticsearch 中的实现方式。 本文是三篇系列文章中的第一篇,将深入探讨向量搜…

Gitee AI上线:开启免费DeepSeek模型新时代

一、引言 在当今数字化浪潮汹涌澎湃的时代,人工智能(AI)已成为推动各行业变革与发展的核心驱动力。从智能语音助手到图像识别技术,从自动驾驶汽车到金融风险预测,AI的应用无处不在,深刻地改变着我们的生活和…

2025蓝桥杯JAVA编程题练习Day3

1.黛玉泡茶【算法赛】 问题描述 话说林黛玉闲来无事,打算在潇湘馆摆个茶局,邀上宝钗、探春她们一起品茗赏花。黛玉素来讲究,用的茶杯也各有不同,大的小的,高的矮的,煞是好看。这不,她从柜子里…

青少年编程与数学 02-008 Pyhon语言编程基础 25课题、文件操作

青少年编程与数学 02-008 Pyhon语言编程基础 25课题、文件操作 一、文件操作二、文本文件读取文本文件写入文本文件追加文本到文件修改文本文件复制文本文件文件编码错误处理 三、JSON文件读取JSON文件写入JSON文件修改JSON文件处理大型JSON文件错误处理 四、练习1. 将JSON文件…

绿虫光伏仿真设计软件基于Unity3D引擎的革命性突破

绿虫光伏仿真设计软件凭借其技术突破与功能创新,正在重塑光伏电站设计领域的行业范式。以下从技术架构、功能创新及行业价值三个维度深度解析其核心竞争力: 一、颠覆性技术架构 1、游戏引擎赋能工业软件 采用Unity3D引擎构建底层架构,实现影…