【redis使用及数据结构篇】——String类型

redis中其他几种数据类型:
List类型使用及底层结构
hash类型使用及底层结构
set类型使用及底层结构
Zset类型使用及底层结构

一、简单使用

1.基本用法

#值的基本设置与获取
127.0.0.1:6379> set k1 v1    #给k1设置值v1
OK
127.0.0.1:6379> get k1		 #获得k1对应的值
"v1"
127.0.0.1:6379> keys *		 #获得所有的key
1) "seckillGoods:1"
2) "seckillGoods:2"
3) "user:9d6ca146f0f049c29029649e8cad042c"
4) "k1"
5) "user:a9540871920043a2a7d4c834d67762c7"
6) "name"
127.0.0.1:6379> exists k1	 #判断k1是否存在
(integer) 1
127.0.0.1:6379> append k1 hello     #将hello添加到k1对应的值v1后面,如果当前key不存在相当于set
(integer) 7
127.0.0.1:6379> get k1		
"v1hello"
127.0.0.1:6379> strlen k1	 #获得k1对应的值v1的长度
(integer) 7
127.0.0.1:6379>

----------------------------------------------------------------------------
#数据自增
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> incr views      #自增1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views		#自减1
(integer) 1
127.0.0.1:6379> incrby views 10		#设置步长(10),指定增量
(integer) 11
127.0.0.1:6379> get views
"11"
127.0.0.1:6379> decrby views 2		#自减特定的步长(2)
(integer) 9
127.0.0.1:6379> get views
"9"

------------------------------------------------------------------------------
#截取指定范围字符串
127.0.0.1:6379> set key1 "hello,i am lihua"
OK
127.0.0.1:6379> getrange key1 0 4      #通过getrange截取指定下标字符串,闭区间!
"hello"
127.0.0.1:6379> getrange key1 0 -1     #0 ~ -1表示完整字符串
"hello,i am lihua"

#替换指定范围字符串
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> setrange key2 1 xx    #1表示从下标1开始替换,xx表示替换的值
(integer) 7							  #xx有多少位,就会从1开始向后替换多少位
127.0.0.1:6379> get key2
"axxdefg"
127.0.0.1:6379>

----------------------------------------------------------------------------------
#设置过期时间

#setex(set with expire)      #设置过期时间
#setex  key  time  value     #time表示过期时间

127.0.0.1:6379> setex key3 30 hello    
OK
127.0.0.1:6379> ttl key3
(integer) 17
 
#setnx(set if not exist)	  #不存在则设置,如果存在则设置失败(常用于分布式锁)
							  #直接set的话,如果该key存在则会覆盖之前的value
							  
127.0.0.1:6379> setnx key4 xiaoming
(integer) 1                               #返回1表示操作成功,返回0表示操作失败
127.0.0.1:6379> get key4
"xiaoming"
127.0.0.1:6379> setnx key4 xiaohong
(integer) 0
127.0.0.1:6379> get key4
"xiaoming"
127.0.0.1:6379>

-----------------------------------------------------------------------------------
#批量设置和获取
#mset key1 value1 key2 value2...
#mget key1 key2...
#msetnx      不存在则设置

127.0.0.1:6379> mset k2 v2 k3 v3
OK
127.0.0.1:6379> mget k2 k3
1) "v2"
2) "v3"

-----------------------------------------------------------------------------------
#对象的设置
set user:1 {name:zhangsan,age:3}     #设置一个key为user:1,value为json字符串保存一个对象

# “:”和mset的巧妙使用      user:{id}:{filed}
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"
127.0.0.1:6379>

--------------------------------------------------------------------------------------
#一个组合命令
getset  #先get后set

127.0.0.1:6379> getset db redis        #如果不存在,则返回nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb      #如果存在值,获取原来的值,并设置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"

2.使用场景

  • 计数器
  • 对象缓存存储

二、底层结构

首先我们要知道,C语言的字符串是存在一些不足的:

  • 获取字符串长度的时间复杂度为 O(N),因为 需要遍历;
  • 字符串的结尾是以 ‘\0’ 字符标识,字符串里面不能包含有 ‘\0’ 字符,因此不能保存二进制数据;
  • 字符串操作函数不高效且不安全,比如有缓冲区溢出的风险,有可能会造成程序运行终止;

而redis为了解决上面的问题,自己设计了一个名为SDS(simple dynamic string)的字符串结构。

1.结构设计

image-20220503160800243

  • len:记录了字符串长度

  • **alloc:分配给字符数组的空间长度。**在修改字符串的时候,可以通过 alloc - len 计算出剩余的空间大小,可以用来判断空间是否满足修改需求,如果不满足的话,就会自动扩容。

  • flags:用来表示不同类型的 SDS。一共设计了 5 种类型,分别是 sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64。

  • buf[]:字符数组,用来保存实际数据。不仅可以保存字符串,也可以保存二进制数据。

2.问题解决

  • O(1)复杂度获取字符串长度。

    直接返回len变量的值就好。

  • 二进制安全。

    SDS 改进后,不需要用 “\0” 字符来标识字符串结尾了,用len变量记录长度就可以,所以可存储包含 ‘\0’的数据。

  • 不会发生缓冲区溢出。

    当空间不足时会自动进行扩容。

  • 节省内存空间。

    通过不同类型的结构体,可以灵活保存不同的字符串,有效节省了空间。

参考[小林coding]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值