Redis——数据结构之string

本文深入探讨了Redis中String类型的基础知识与应用,包括基本概念、数据存储特性、以及多种实用命令的使用方法,如set、get、getset、setrange、getrange等,同时还介绍了msetnx、del、incr、decr、incrby、decrby、append、bitop、bitcount等高级功能。

字符串类型是 redis 中最为基础的数据存储类型,是一个由字节组成的序列,它可以接受任何格式的数据,如JPEG图像数据或json对象描述信息等,是标准的key-value,一般用来存字符串、整数和浮点数。value最多可容纳的数据长度为512MB。

Key定义的注意点:

  • 不要过长,
  • 不要过短,
  • 统一的命名规范

1. String常用命令

set 赋值: 

127.0.0.1:6379> set age 18
OK

get  取值:

127.0.0.1:6379> get age
"18"

getset  获取并设置值

127.0.0.1:6379> getset age 19
"18"
127.0.0.1:6379> get age
"19"
setrange/getrange
 
【命令格式】:
 

setrange key offset value

getrange key start end

SETRANGE 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。不存在的 key 当作空白字符串处理。
SETRANGE 命令会确保字符串足够长以便将 value 设置在指定的偏移量上,如果给定key原来储存的字符串长度比偏移量小,那么原字符和偏移量之间的空白将用零字节(zerobytes, "\x00" )来填充

GETRANGE 返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。负数偏移量表示从字符串最后开始计数,-1 表示最后一个字符,-2 表示倒数第二个,以此类推。
GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。不支持回绕操作。

127.0.0.1:6379> set hello "hello world!"
OK
127.0.0.1:6379> setrange hello 6 "redis"
(integer) 12
127.0.0.1:6379> get hello
"hello redis!"
127.0.0.1:6379> setrange hello 13 ^_^
(integer) 16
127.0.0.1:6379> get hello
"hello redis!\x00^_^"
127.0.0.1:6379> 
127.0.0.1:6379> set hello "hello world"
OK
127.0.0.1:6379> getrange hello 0 -1
"hello world"
127.0.0.1:6379> getrange hello 0 3
"hell"
127.0.0.1:6379> getrange hello -1 -5
""
127.0.0.1:6379> getrange hello -5 -1
"world"
msetnx key value [key value ...]
 

同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。

即使只有一个给定 key 已存在, MSETNX 也会拒绝执行所有给定 key 的设置操作。

MSETNX 是原子性的,因此它可以用作设置多个不同 key 表示不同字段(field)的唯一性逻辑对象(unique logic object),所有字段要么全被设置,要么全不被设置。

del 删除

127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)

incr 自增 

127.0.0.1:6379> incr n
(integer) 1
127.0.0.1:6379> get n
"1"
127.0.0.1:6379> 
127.0.0.1:6379> incr age
(integer) 20

decr 自减

127.0.0.1:6379> decr i
(integer) -1
127.0.0.1:6379> decr age
(integer) 19

 

incrby 指定增量值

127.0.0.1:6379> get age
"19"
127.0.0.1:6379> incrby age 4
(integer) 23

 

decrby 指定减量值

127.0.0.1:6379> decrby age 6
(integer) 17

append 追加字符串

假如没定义 直接赋值

127.0.0.1:6379> append str hello
(integer) 5
127.0.0.1:6379> append str Word
(integer) 9
127.0.0.1:6379> get str
"helloWord"

bitop operation destkey key [key ...]

 

对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。

operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种

除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。

当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。

 

127.0.0.1:6379> setbit bit1 2 1  # bit1  001
(integer) 0
127.0.0.1:6379> setbit bit2 1 1  # bit2  011
(integer) 0
127.0.0.1:6379> setbit bit2 2 1
(integer) 0
127.0.0.1:6379> bitop and result bit1 bit2
(integer) 1
127.0.0.1:6379> getbit result 0
(integer) 0
127.0.0.1:6379> getbit result 1
(integer) 0
127.0.0.1:6379> getbit result 2
(integer) 1
bitcount key [start] [end]

 

计算给定字符串中,被设置为 1 的比特位的数量。
一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。start 和 end 参数的设置可以使用负数值
不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

127.0.0.1:6379> bitcount bit2
(integer) 2
127.0.0.1:6379> bitcount empty
(integer) 0

 

<think>嗯,用户想了解Redis 6.0支持的数据结构及其特性。这个问题很专业,需要系统整理Redis核心数据结构在6.0版本中的实现和优化。 首先回忆Redis 6.0的重要更新,虽然数据结构本身没有新增类型,但内存管理和线程模型有重大改进。用户引用的资料[1][4]提到6.0版本提升了性能和扩展性,特别是客户端缓存特性[^4],这对数据结构的使用效率有间接影响。 从基础数据结构开始梳理: 字符串(String)作为最基础的类型,在6.0中embstr编码优化了短字符串存储,引用[2]提到的list结构体其实也适用于所有数据结构——Redis都采用类似的设计模式:用专属结构体管理元数据(如len字段),再指向具体存储节点。哈希表(Hash)的ziplist转hashtable的阈值值得说明,这个直接影响内存效率。 列表(List)要重点讲quicklist结构,这是3.2版本引入的,但6.0的线程IO优化使其并发性能提升。用户引用[2]的list结构体代码很关键,其中dup和free函数指针说明Redis支持深拷贝[^2]。集合(Set)的整数集合升级机制需要举例说明,比如$SADD$命令触发intset转hashtable的过程。 有序集合(ZSet)的ziplist+skiplist双结构是难点,要解释跳表如何实现$O(logN)$查询。引用[4]的客户端缓存特性[^4]对频繁访问的有序集合特别有利,因为可以避免重复查询。位图(Bitmap)和HyperLogLog虽然基于字符串,但它们的位操作指令如$SETBIT$需要单独说明。 地理空间索引(Geospatial)本质是有序集合,但GEOADD命令的坐标编码机制值得展开。流(Stream)作为5.0新增结构,在6.0中稳定性增强,要强调消息ID的时序性和消费者组特性。 最后补充6.0的线程安全改进:虽然数据结构操作本身还是单线程,但网络IO多线程化提升了大value操作的吞吐量。引用[3]的bind配置[^3]看似无关,实则影响数据结构服务稳定性——错误的网络配置可能导致数据丢失。 用户可能混淆了数据结构版本差异,需要明确6.0是优化而非新增结构。相关问题的设计要覆盖使用场景(如为什么选Hash而不是String存储对象)和性能对比(如ZSet的跳表查询复杂度证明)。</think>Redis 6.0 延续了其丰富的数据结构支持,以下是核心数据结构及其特性的详细解析: ### 一、核心数据结构 1. **字符串String)** - 存储文本、二进制数据(如图片)或数值 - 最大容量 512MB - 特殊操作: ```bash INCR counter # 原子计数器 APPEND log "msg" # 追加操作 BITCOUNT user:1 # 位运算 ``` 2. **哈希(Hash)** - 存储字段-值映射表,适合对象存储 - 底层实现: - `ziplist`(元素少时,内存紧凑) - `hashtable`(元素多时,$O(1)$ 复杂度) - 示例: ```bash HSET user:1000 name "Alice" age 30 HGETALL user:1000 ``` 3. **列表(List)** - 双向链表结构,支持左右插入/弹出 - 关键特性: - 可实现队列(LPUSH/RPOP)或栈(LPUSH/LPOP) - 阻塞操作:`BLPOP` 实现消息队列 - 底层结构:`quicklist`(ziplist 链表,平衡内存和速度) 4. **集合(Set)** - 无序唯一元素集合 - 支持交并差集运算($SINTER/SUNION/SDIFF$) - 底层实现: - `intset`(纯整数时) - `hashtable`(其他类型) 5. **有序集合(Sorted Set)** - 元素关联分值,按分值排序 - 底层结构: - `ziplist`(小规模) - **跳表(skiplist)+ 字典**(大规模,$O(logN)$ 复杂度) - 范围操作: ```bash ZRANGEBYSCORE players 1000 2000 # 按分值检索 ``` ### 二、高级数据结构 6. **位图(Bitmap)** - 基于字符串的位操作 - 适用场景:实时用户签到统计 ```bash SETBIT user:2024:sign 15 1 # 记录第15天签到 BITCOUNT user:2024:sign # 统计总签到 ``` 7. **HyperLogLog** - 基数估算(误差约 0.81%) - 内存仅需 12KB ```bash PFADD ip_log 192.168.1.1 PFCOUNT ip_log # 估算独立IP数 ``` 8. **地理空间索引(Geospatial)** - 存储经纬度坐标 - 支持距离计算(GEODIST)和半径查询(GEORADIUS) ```bash GEOADD cities 116.40 39.90 Beijing GEOSEARCH cities FROMLONLAT 116.4 39.9 BYRADIUS 100 km ``` 9. **流(Stream)** - 消息队列实现(Redis 5.0+) - 特性: - 消息持久化 - 消费者组(Consumer Groups) - 消息回溯 ```bash XADD orders * product "Book" price 29.9 XREAD GROUP group1 consumer1 COUNT 1 STREAMS orders > ``` ### 三、Redis 6.0 的增强特性 1. **多线程网络 I/O** - 处理网络请求使用多线程(执行命令仍单线程) - 提升高并发场景吞吐量 2. **客户端缓存(Client-side Caching)** - 服务端跟踪客户端缓存(`RESP3` 协议支持) - 主动通知缓存失效(避免脏读)[^4] 3. **ACL 权限控制** - 细粒度命令权限管理 ```bash ACL SETUSER alice ON >pass123 +@read ~cache:* ``` 4. **TLS 加密传输** - 增强客户端-服务端通信安全[^3] ### 四、数据结构选择建议 | 场景 | 推荐结构 | 原因 | |------|----------|------| | 对象属性存储 | Hash | 字段独立存取 | | 排行榜 | Sorted Set | 天然排序能力 | | 消息队列 | Stream | 消息持久化和消费组 | | UV统计 | HyperLogLog | 低内存消耗 | > Redis 6.0 通过优化内存分配(jemalloc 改进)和网络层多线程,显著提升了大型数据结构(如数十万元素的 Sorted Set)的操作效率[^1][^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值