Redis五大数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sorted set:有序集合)。
一、介绍
String 是Redis 最基本的类型,一个 key 对应一个 value。
特点
- 二进制安全的
- 可以包含任何数据:序列化的对象、简单的字符串、复杂的字符串(xml、json)、数字(整数、浮点数)、二进制(图片、音频、视频)
- value值最大能存储 512MB
如果只用String类型,可以被看作加上持久化特性(服务器重启之后,数据不丢失)的memcache
二进制安全:在传输数据时,保证二进制数据的信息安全,也就是不被篡改、破译等,如果被攻击,能够及时检测出来
二进制安全特点:
1、编码、解码发生在客户端完成,执行效率高
2、不需要频繁的编解码,不会出现乱码
二、操作命令
1、设置/获取
命令 | 描述 | 返回值 |
set | 1. 给一个key添加字符串类型的值 2. key已存在,则新值会覆盖旧值(注意:会无视类型) 3. SET设置后的键,之前的生存时间TTL会被清除 4. 也可设置生存时间,但非原子操作 | 成功:OK 失败:nil |
mset | 1. 同时设置一个或多个Key-Value 2. key已存在,则新值会覆盖旧值 3. 原子操作,要么同时成功或失败(不存在部分成功或失败) | 成功:OK |
setex | 1. 给一个key添加字符串类型的值,并指定生存时间(单位:秒) 2. key已存在,则新值会覆盖旧值 3. 原子操作,设置失败或者指定生存时间失败,会恢复初始状态 | 成功:OK 失败:返回错误信息 |
setnx | key不存在,才会给一个key添加字符串类型的值(否则不做操作) | 成功:1 失败:0 |
psetex | 1.给一个key添加字符串类型的值,并指定生存时间(单位:毫秒) 2. 原子操作,设置失败或者指定生存时间失败,会恢复初始状态 | 成功:OK 失败:返回错误信息 |
setrange | 1. key存在:从offset处开始插入value,如offset的值大于该键字符串长度,用NULL补充到该长度,再末尾插入value。 2. key不存在:设置新值,并补充offset个NULL:“offset个NULL+value” 修改或者设置一个键的字符串类型值的内容 例:键值为:name-wpf 获取:setrange name 2 f 返回"wpo" | 成功:返回字符串长度 失败:返回错误信息 |
append | 1. key存在,则在后面追加value的内容 2. key不存在,会创建一个key,将其值设置为空字符串,并在后追加内容 | 返回成功的字符串长度 |
获取: | ||
get | 1. 返回key关联的value值 2. Key不存在返回nil 3. 如果Key不是String类型,返回错误(GET只用于处理字符串) | 存在:返回子串内容 不存在:返回nil 非string:返回错误信息 |
mget | 查询所有指定的key的值 | 成功:返回所有值 不存在:返回nil 非string类型:返回nil |
getrange | 查询指定start和end位置的字符串的子串 注:start 和 end 可以为负数,-1:最后一个字符 -2:倒数第二个字符 例:键值为:name-java 获取:getrange name 1 2 返回"av" | 存在:返回子串内容 不存在:返回空字符串 非string:返回错误信息 |
getset | 1. key存在:设置新值,但仅返回原来的旧值,下次获取则返回新值 2. key不存在:设置新值,返回nil,下次获取则返回新值 原子的给一个key设置value并且将旧值返回 | 非string:返回错误信息 |
strlen | 返回key的字符串长度 | 不存在:返回0 非string:返回错误信息 |
2、计数(特殊的字符串计数操作)
命令 | 描述 | 语法 |
incr | 1. key存在:执行key的值+1,返回其增加后的值 2. key不存在:值初始为0,再执行+1 功能:将key中存储的数字值+1 | incr [key] |
incrby | 1. key存在:执行key的值+increment增量,返回其增加后的值 2. key不存在:值初始为0,再执行+increment 功能:将key中存储的数字值 +increment增量值 | incrby [key] [increment] |
incrbyfloat | 同incrby,增量值为浮点数 | incrbyfloat [key] [increment] |
decr | 同incr,-1操作 | decr [key] |
decrby | 同incrby,-增量值 | decrby [key] [decrement] |
三、演示操作命令
▶ set 语法: set key value [EX seconds] [PX milliseconds]
功能:1. 给一个key添加字符串类型的值
[127.0.0.1:6379> keys * # 获取所有key
(empty array) # 空库
[127.0.0.1:6379> set age 18 # 1.设置age=18 注:key不存在
OK
[127.0.0.1:6379> get age # 2.获取age的值
"18" # age的值
[127.0.0.1:6379> set age wpf # 3.设置age=wpf 注:如key已存在,则覆盖旧值并无视类型
OK
[127.0.0.1:6379> get age
"wpf" # 旧值被新值覆盖
[127.0.0.1:6379>
功能: 2.指定生存时间的值 [ EX seconds | PX millisecon ] 生存时间:秒|毫秒
[127.0.0.1:6379> set name jack ex 6 # 设置key为name,值为jack,指定生存时间6秒
OK
[127.0.0.1:6379> ttl name # [ttl key] 查看该key剩余生存时间
(integer) 4 # 还剩4秒
[127.0.0.1:6379> ttl name # -2表示已过期
(integer) -2
[127.0.0.1:6379> get name # 过期后,再次获取key为name的值:nil
(nil)
▶ mset 语法: mset key1 value key2 value ...
功能:原子操作,同时设置一个或多个Key-Value
# [mset key1 value key2 value ...] 同时设置多个键值对
[127.0.0.1:6379> mset name jack age 18 high 175
OK
[127.0.0.1:6379> keys * # [keys *] 查看全部key
1) "high"
2) "age"
3) "name"
[127.0.0.1:6379> mget name age high # [mget key1 key2..] 同时获取多个指定的key的值
1) "jack"
2) "18"
3) "175"
[127.0.0.1:6379> mset name lisa birth 1996 # 已存在name这个key,重复设置会覆盖旧值
OK
[127.0.0.1:6379> mget name age high birth
1) "lisa" # 旧值是jack,已被新值覆盖
2) "18"
3) "175"
4) "1996"
▶ setex 语法: setex key seconds value
功能:原子操作,给一个key添加字符串类型的值,并指定生存时间(单位:秒)
[127.0.0.1:6379> setex name 10 wpf # 设置key为name,指定生存10秒,value为wpf
OK
[127.0.0.1:6379> ttl name # [ttl key] 查看该key剩余生存时间
(integer) 8
127.0.0.1:6379> ttl name
(integer) 4
[127.0.0.1:6379> ttl name # -2表示已过期
(integer) -2
[127.0.0.1:6379> get name # 过期后,再次获取key为name的值:nil
(nil)
▶ setnx 语法: setnx key value
功能:如果key不存在,则给key设置值,如果key已存在,则设置无效
[127.0.0.1:6379> keys * # [keys *] 查看全部key
(empty array) # 空库
[127.0.0.1:6379> setnx name rose # 如不存在为name的key,则设置key为name,值为rose
(integer) 1 # 成功:返回1
[127.0.0.1:6379> get name
"rose"
[127.0.0.1:6379> setnx name jack # 为name的key已经存在了,继续设置则无效
(integer) 0 # 失败:返回0
[127.0.0.1:6379> get name
"rose"
▶ append 语法: append key value
功能:追加字符串内容(等同于StringBuffer里的 append( ) 方法)
[127.0.0.1:6379> keys * # [keys *] 查看全部key
(empty array) # 空库
[127.0.0.1:6379> append name jack # 为name的key不存在,则设置key并赋值为jack
(integer) 4
[127.0.0.1:6379> get name # [get key] 获取该key的值
"jack"
[127.0.0.1:6379> append name lisa # name的key已存在,则在字符串后面拼接新内容
(integer) 8 # 成功:返回字符串长度
[127.0.0.1:6379> get name
"jacklisa"
▶ setrange 语法: setrange key offset value
功能:修改或者设置一个键的字符串类型值的内容
[127.0.0.1:6379> set name chinese # 设置key-value:name-chinese
OK
[127.0.0.1:6379> get name # [get key] 获取该key的值
"chinese"
# 1. 若key存在,从offset处开始插入value
[127.0.0.1:6379> setrange name 3 oo # 从offset处插入value offset:3 value:oo
(integer) 7
[127.0.0.1:6379> get name
"chioose"
# 2. 如offset的值大于该键字符串长度,用NULL补充到该长度,再末尾插入value。
[127.0.0.1:6379> setrange name 8 kk
(integer) 10
[127.0.0.1:6379> get name
"chioose\x00kk"
# 2.若key不存在:设置新值,并补充offset个NULL,即:“offset个NULL+value”
[127.0.0.1:6379> setrange logo 2 mm
(integer) 4
[127.0.0.1:6379> get logo
"\x00\x00mm"
▶ getrange 语法: getrange key start end
功能:查询指定start 和 end 位置的字符串的子串
注:start 和 end 可以为负数,-1:最后一个字符 -2:倒数第二个字符
[127.0.0.1:6379> set name chinese # 设置一个key为name,value为chinese
OK
[127.0.0.1:6379> getrange name 1 3 # 获取并返回一个从 [1-3] 位置的字符串的子串
"hin"
[127.0.0.1:6379> getrange name 0 -1 # ...从 [1-最后] 位置的字符串的子串
"chinese"
[127.0.0.1:6379> getrange name -1 -1 # ...从 [最后-最后] 位置的字符串的子串
"e"
[127.0.0.1:6379> getrange name 1 -2 # ...从 [1-倒数第二个字符] 位置的字符串的子串
"hines"
▶ getset 语法: getset key value
功能:设置一个key的新值,并返回该key原本的旧值
# 1. key不存在:设置key-value:name-jack,并返回key为name的值
[127.0.0.1:6379> getset name jack
(nil) # 名为name的key不存在,返回nil(说明无旧值)
[127.0.0.1:6379> get name # [get key] 获取该key的值,为上述的getset的赋值:jack
"jack"
# 2. key存在:
[127.0.0.1:6379> getset name lisa # 设置名为name的key的新值为lisa,并返回它的旧值
"jack"
[127.0.0.1:6379> get name # 获取该key的值,为上述的getset的赋值:lisa
"lisa"
▶ srtlen 语法: strlen key value
功能:返回该key的字符串值的长度
[127.0.0.1:6379> set name china # 设置key为name,value为china
OK
# 1. key存在:返回该key的值的长度length
[127.0.0.1:6379> strlen name
(integer) 5
# 2. key不存在:返回0
[127.0.0.1:6379> strlen age
(integer) 0
——特殊的计数命令演示
▶ incr 语法: incr key
功能:将key中存储的数字值+1
num不存在,执行 incr num 会将num的值初始为0,再执行+1 ,如果key存在则直接:+1,返回其执行结果。
▶ incrby 语法: incrby key increment
功能:将key中存储的数字值+增量值
num不存在,执行 incrby num 会将num的值初始为0,再执行+增量值 ,如果key存在则直接执行:+增量值,返回其执行结果。
▶ incrbyfloat 语法: incrbyfloat key increment
功能:将key中存储的数字值+浮点增量值
num不存在,执行 incrbyfloat num 会将num的值初始为0,再执行+浮点增量值 ,如果key存在则直接执行:+浮点增量值,返回其执行结果。
四、应用场景
- String通常用于保存单个字符串或JSON字符串数据
- 因String是二进制安全的,所以你完全可以把一个图片文件的内容作为字符串来存储
- 计数器(常规key-value缓存应用。常规计数: 微博数, 粉丝数)
可以利用redis的INCR、INCRBY、DECR、DECRBY等指令来实现原子计数的效果。
假如,在某种场景下有3个客户端同时读取了mynum的值(值为2),然后对其同时进行了加1的操作,则最后mynum的值一定是5。
——不少网站都利用redis的这个特性来实现业务上的统计计数需求。
- 原先单机环境中统计在线人数,变成分布式部署之后可以使用INCR/DECR
- 由于Redis有极高的读写性能,一些秒杀的场景库存增减可以基于Redis来做而非直接操作DB
五、String 结构优缺点
-
优点:简单直观,每个属性都支持 更新操作。
-
缺点:占用 过多的键,内存占用量 较大,同时用户信息内聚性比较差