Redis基础-五大数据类型
Redis数据类型
五大数据类型
- string字符串(可以为整形、浮点型和字符串,统称为元素)
- list列表(实现队列,元素不唯一,先入先出原则)
- set集合(各不相同的元素)
- hashhash散列值(hash的key必须是唯一的)
- sort set有序集合
三种特殊数据类型
- geospatial
- Hyperloglog
- Bitmap
Redis-Key
EXISTS判断key是否存在

move移动key到指定数据库(编号 16个)

EXPIRE指令 设置key的生存日期ttl指令查看当前key的生存时间
查看代码
127.0.0.1:6379> EXPIRE name 10 # 表示10秒后
(integer) 1
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
(nil)
type查看当前key的类型
127.0.0.1:6379> type name
string
127.0.0.1:6379> type age
string
String(字符串)
APPEND命令
如果 key 已经存在并且是一个字符串,APPEND命令将value追加到key原来的值的末尾。如果key 不存在,APPEND就简单地将给定key 设为value,就像执行SET key value一样。
# 对不存在的 key 执行 APPENDredis> EXISTS myphone # 确保 myphone 不存在(integer) 0
redis> APPEND myphone "nokia" # 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"(integer) 5 # 字符长度
# 对已存在的字符串进行 APPENDredis> APPEND myphone " - 1110" # 长度从 5 个字符增加到 12 个字符(integer) 12
redis> GET myphone"nokia - 1110"
STRLEN命令
返回 key 所储存的字符串值的长度。当 key 储存的不是字符串值时,返回一个错误。
# 获取字符串的长度
redis> SET mykey "Hello world"
OK
redis> STRLEN mykey
(integer) 11
# 不存在的 key 长度为 0
redis> STRLEN nonexisting
(integer) 0
GETRANGE命令
GETRANGE key start end,返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推。
返回值: 截取得出的子字符串。
redis> SET greeting "hello, my friend"
OK
redis> GETRANGE greeting 0 4 # 返回索引0-4的字符,包括4。
"hello"
redis> GETRANGE greeting -1 -5 # 不支持回绕操作
""
redis> GETRANGE greeting -3 -1 # 负数索引
"end"
redis> GETRANGE greeting 0 -1 # 从第一个到最后一个
"hello, my friend"
redis> GETRANGE greeting 0 1008611 # 值域范围不超过实际字符串,超过部分自动被符略
"hello, my friend"
SETRANGE命令
用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始。 SETRANGE命令会确保字符串足够长以便将 value 设置在指定的偏移量上,如果给定key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但你设置的 offset 是 10 ),那么原字符和偏移量之间的空白将用零字节(zerobytes, "\x00" )来填充。 返回值: 被 SETRANGE 修改之后,字符串的长度。SETRANGE
# 对非空字符串进行 SETRANGE
redis> SET greeting "hello world"
OK
redis> SETRANGE greeting 6 "Redis"
(integer) 11
redis> GET greeting
"hello Redis"
# 对空字符串/不存在的 key 进行 SETRANGE
redis> EXISTS empty_string
(integer) 0
redis> SETRANGE empty_string 5 "Redis!" # 对不存在的 key 使用 SETRANGE
(integer) 11
redis> GET empty_string # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
INCR命令
将 key 中储存的数字值增一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 这是一个针对字符串的操作,因为Redis 没有专用的整数类型,所以key 内储存的字符串被解释为十进制 64 位有符号整数来执行 INCR 操作。 返回值: 执行 INCR 命令之后 key 的值。INCR
redis> SET page_view 20
OK
redis> INCR page_view
(integer) 21
redis> GET page_view # 数字值在 Redis 中以字符串的形式保存
"21"
模式:计数器
计数器是Redis的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向Redis发送一个INCR命令。 比如在一个 web 应用程序中,如果想知道用户在一年中每天的点击量,那么只要将用户 ID 以及相关的日期信息作为键,并在每次用户点击页面时,执行一次自增操作即可。 比如用户名是 peter ,点击时间是 2012 年 3 月 22 日,那么执行命令INCR peter::2012.3.22 。 可以用以下几种方式扩展这个简单的模式:
-
可以通过组合使用INCR和EXPIRE,来达到只在规定的生存时间内进行计数(counting)的目的。
-
客户端可以通过使用GETSET命令原子性地获取计数器的当前值并将计数器清零。
-
使用其他自增/自减操作,比如DECR和INCRBY,用户可以通过执行不同的操作增加或减少计数器的值,比如在游戏中的记分器就可能用到这些命令。
DECR命令
将 key 中储存的数字值减一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 返回值: 执行 DECR 命令之后 key 的值。DECR
redis> SET failure_times 10 # 对存在的数字值 key 进行 DECROK
redis> DECR failure_times(integer) 9
redis> EXISTS count #对不存在的 key 值进行 DECR(integer) 0
redis> DECR count(integer) -1
redis> SET company YOUR_CODE_SUCKS.LLC # 对存在但不是数值的 key 进行 DECROK
redis> DECR company(error) ERR value is not an integer or out of range
INCRBY(与DECRBY相同)命令
INCRBY key increment,将key 所储存的值加上增量increment。如果key不存在,那么key的值会先被初始化为0,然后再执行INCRBY命令。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
INCRBY
redis> SET rank 50 # key 存在且是数字值
OK
redis> INCRBY rank 20
(integer) 70
redis> GET rank
"70"
redis> EXISTS counter # key 不存在时
(integer) 0
redis> INCRBY counter 30
(integer) 30
redis> GET counter
"30"
redis> SET book "long long ago..." # key 不是数字值时
OK
redis> INCRBY book 200
(error) ERR value is not an integer or out of range
SETNX命令
SETNX【SET if Not eXists】 key value,将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX不做任何动作。 返回值: 设置成功,返回 1 。 设置失败,返回 0 。SETNX
redis> EXISTS job # job 不存在
(integer) 0
redis> SETNX job "programmer" # job 设置成功
(integer) 1
redis> SETNX job "code-farmer" # 尝试覆盖 job ,失败
(integer) 0
redis> GET job # 没有被覆盖
"programmer"
SETEX命令
SETEX key seconds value,将值 value 关联到 key ,并将 key 的生存时间设为 seconds(以秒为单位)。如果 key 已经存在, SETEX命令将覆写旧值。 这个命令类似于以下两个命令:
SET key value
EXPIRE key seconds # 设置生存时间
返回值: 设置成功时返回 OK 。 当 seconds 参数不合法时,返回一个错误。
不同之处是,SETEX 是一个原子性(atomic)操作,关联值和设置生存时间两个动作会在同一时间内完成,该命令在 Redis 用作缓存时,非常实用。
SETEX
redis> SETEX cache_user_id 60 10086 #在 key 不存在时进行 SETEX
OK
redis> GET cache_user_id # 值
"10086"
redis> TTL cache_user_id # 剩余生存时间
(integer) 49
redis> SET cd "timeless" # key 已经存在时,SETEX 覆盖旧值
OK
redis> SETEX cd 3000 "goodbye my love"
OK
redis> GET cd
"goodbye my love"
redis> TTL cd
(integer) 2997
MGET命令
返回所有(一个或多个)给定 key 的值。如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。 返回值: 一个包含所有给定 key 的值的列表。MGET
redis> SET redis redis.com
OK
redis> SET mongodb mongodb.org
OK
redis> MGET redis mongodb
1) "redis.com"
2) "mongodb.org"
redis> MGET redis mongodb mysql # 不存在的 mysql 返回 nil
1) "redis.com"
2) "mongodb.org"
3) (nil)
MSET命令
同时设置一个或多个 key-value 对。如果某个给定 key 已经存在,那么MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用MSETNX命令:它只会在所有给定 key 都不存在的情况下进行设置操作。 MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。 返回值: 总是返回 OK (因为 MSET 不可能失败)MSET
redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK
redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"
# MSET 覆盖旧值例子
redis> SET google "google.hk"
OK
redis> MSET google "google.com"
OK
redis> GET google
"google.com"
MSETNX命令
同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。即使只有一个给定 key 已存在,MSETNX 也会拒绝执行所有给定 key 的设置操作。(因为MSETNX是原子性操作,所以一个失败全部失败) 返回值: 当所有 key 都成功设置,返回 1 。
如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。
MSETNX
# 对不存在的 key 进行 MSETNX
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1
redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"
# MSET 的给定 key 当中有已存在的 key
redis> MSETNX rmdbs "Sqlite" language "python" # rmdbs 键已经存在,操作失败
(integer) 0
redis> EXISTS language # 因为 MSET 是原子性操作,language 没有被设置
(integer) 0
redis> GET rmdbs # rmdbs 也没有被修改
"MySQL"
对象
对象
# 设置一个user:1 对象 值为json字符保存一个对象#这里的key是一个巧妙的设计 user:{id}:{field},对此设计在Redis中是完全ok的
set user:1{name:zhangsan,age:3}
127.0.0.1:6379> MGET user:1:name user:1:age
1) "zhangrui"
2) "2"
GETSET命令
将给定 key 的值设为 value ,并返回 key 的旧值(old value)。当 key 存在但不是字符串类型时,返回一个错误。 返回值: 返回给定 key 的旧值。 当 key 没有旧值时,也即是, key 不存在时,返回 nil 。GETSET
redis> GETSET db mongodb # 没有旧值,返回 nil
(nil)
redis> GET db
"mongodb"
redis> GETSET db redis # 返回旧值 mongodb
"mongodb"
redis> GET db
"redis"
redis> INCR mycount
(integer) 11
redis> GETSET mycount 0 # 一个原子内完成 GET mycount 和 SET mycount 0 操作
"11"
redis> GET mycount # 计数器被重置
"0"
List(列表)
LLEN命令
# 空列表
redis> LLEN job
(integer) 0
# 非空列表
redis> LPUSH job "cook food"
(integer) 1
redis> LPUSH job "have lunch"
(integer) 2
redis> LLEN job
(integer) 2
LPUSH命令
# 加入单个元素
redis> LPUSH languages python
(integer) 1
# 加入重复元素
redis> LPUSH languages python
(integer) 2
redis> LRANGE languages 0 -1 # 列表允许重复元素
1) "python"
2) "python"
# 加入多个元素
redis> LPUSH mylist a b c
(integer) 3
redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"
RPUSH命令
# 添加单个元素
redis> RPUSH languages c
(integer) 1
# 添加重复元素
redis> RPUSH languages c
(integer) 2
redis> LRANGE languages 0 -1 # 列表允许重复元素
1) "c"
2) "c"
# 添加多个元素
redis> RPUSH mylist a b c
(integer) 3
redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"
redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"
LPUSHX命令
# 对空列表执行 LPUSHX
redis> LLEN greet # greet 是一个空列表
(integer) 0
redis> LPUSHX greet "hello" # 尝试 LPUSHX,失败,因为列表为空
(integer) 0
# 对非空列表执行 LPUSHX
redis> LPUSH greet "hello" # 先用 LPUSH 创建一个有一个元素的列表
(integer) 1
redis> LPUSHX greet "good morning" # 这次 LPUSHX 执行成功
(integer) 2
redis> LRANGE greet 0 -1
1) "good morning"
2) "hello"
RPUSHX命令
redis> LLEN greet
(integer) 0
redis> RPUSHX greet "hello" # 对不存在的 key 进行 RPUSHX,PUSH 失败。(integer) 0
# key 存在且是一个非空列表
redis> RPUSH greet "hi" # 先用 RPUSH 插入一个元素
(integer) 1
redis> RPUSHX greet "hello" # greet 现在是一个列表类型,RPUSHX 操作成功。(integer) 2
redis> LRANGE greet 0 -1
1) "hi"
2) "hello"
LRANGE命令
超出范围的下标
超出范围的下标值不会引起错误。如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,那么 LRANGE 返回一个空列表。如果 stop 下标比 end 下标还要大,Redis将 stop 的值设置为 end 。
返回值:
一个列表,包含指定区间内的元素。
redis> RPUSH fp-language lisp
(integer) 1
redis> LRANGE fp-language 0 0
1) "lisp"
redis> RPUSH fp-language scheme
(integer) 2
redis> LRANGE fp-language 0 1
1) "lisp"
2) "scheme"
LPOP(RPOP)命令
redis> LLEN course
(integer) 0
redis> RPUSH course algorithm001
(integer) 1
redis> RPUSH course c++101
(integer) 2
redis> LPOP course # 移除头元素
"algorithm001"
----------------------------------------------------------------------------
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> RPOP mylist # 返回被弹出的元素
"three"
redis> LRANGE mylist 0 -1 # 列表剩下的元素
1) "one"
2) "two"
LINDEX命令
redis> LPUSH mylist "World"
(integer) 1
redis> LPUSH mylist "Hello"
(integer) 2
redis> LINDEX mylist 0
"Hello"
redis> LINDEX mylist -1
"World"
redis> LINDEX mylist 3 # index不在 mylist 的区间范围内
(nil)
LREM命令
-
count > 0: 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
-
count < 0: 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
-
count = 0: 移除表中所有与 value 相等的值。
# 先创建一个表,内容排列是
# morning hello morning helllo morning
redis> LPUSH greet "morning"
(integer) 1
redis> LPUSH greet "hello"
(integer) 2
redis> LPUSH greet "morning"
(integer) 3
redis> LPUSH greet "hello"
(integer) 4
redis> LPUSH greet "morning"
(integer) 5
redis> LRANGE greet 0 4 # 查看所有元素
1) "morning"
2) "hello"
3) "morning"
4) "hello"
5) "morning"
redis> LREM greet 2 morning # 移除从表头到表尾,最先发现的两个 morning
(integer) 2 # 两个元素被移除
redis> LLEN greet # 还剩 3 个元素
(integer) 3
redis> LRANGE greet 0 2
1) "hello"
2) "hello"
3) "morning"
redis> LREM greet -1 morning # 移除从表尾到表头,第一个 morning
(integer) 1
redis> LLEN greet # 剩下两个元素
(integer) 2
redis> LRANGE greet 0 1
1) "hello"
2) "hello"
redis> LREM greet 0 hello # 移除表中所有 hello
(integer) 2 # 两个 hello 被移除
redis> LLEN greet
(integer) 0
LTRIM命令
# 情况 1:常见情况, start 和 stop 都在列表的索引范围之内
redis> LRANGE alpha 0 -1 # alpha 是一个包含 5 个字符串的列表
1) "h"
2) "e"
3) "l"
4) "l"
5) "o"
redis> LTRIM alpha 1 -1 # 删除 alpha 列表索引为 0 的元素
OK
redis> LRANGE alpha 0 -1 # "h" 被删除了
1) "e"
2) "l"
3) "l"
4) "o"
# 情况 2:stop 比列表的最大下标还要大
redis> LTRIM alpha 1 10086 # 保留 alpha 列表索引 1 至索引 10086 上的元素
OK
redis> LRANGE alpha 0 -1 # 只有索引 0 上的元素 "e" 被删除了,其他元素还在
1) "l"
2) "l"
3) "o"
# 情况 3:start 和 stop 都比列表的最大下标要大,并且 start < stop
redis> LTRIM alpha 10086 123321
OK
redis> LRANGE alpha 0 -1 # 列表被清空
(empty list or set)
# 情况 4:start 和 stop 都比列表的最大下标要大,并且 start > stop
redis> RPUSH new-alpha "h" "e" "l" "l" "o" # 重新建立一个新列表
(integer) 5
redis> LRANGE new-alpha 0 -1
1) "h"
2) "e"
3) "l"
4) "l"
5) "o"
redis> LTRIM new-alpha 123321 10086 # 执行 LTRIM
OK
redis> LRANGE new-alpha 0 -1 # 同样被清空
(empty list or set)
RPOPLPUSH命令
# source 和 destination 不同
redis> LRANGE alpha 0 -1 # 查看所有元素
1) "a"
2) "b"
3) "c"
4) "d"
redis> RPOPLPUSH alpha reciver # 执行一次 RPOPLPUSH 看看
"d"
redis> LRANGE alpha 0 -1
1) "a"
2) "b"
3) "c"
redis> LRANGE reciver 0 -1
1) "d"
redis> RPOPLPUSH alpha reciver # 再执行一次,证实 RPOP 和 LPUSH 的位置正确
"c"
redis> LRANGE alpha 0 -1
1) "a"
2) "b"
redis> LRANGE reciver 0 -1
1) "c"
2) "d"
# source 和 destination 相同
redis> LRANGE number 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
redis> RPOPLPUSH number number
"4"
redis> LRANGE number 0 -1 # 4 被旋转到了表头
1) "4"
2) "1"
3) "2"
4) "3"
LSET命令
# 对空列表(key 不存在)进行 LSET
redis> EXISTS list
(integer) 0
redis> LSET list 0 item
(error) ERR no such key
# 对非空列表进行 LSET
redis> LPUSH job "cook food"
(integer) 1
redis> LRANGE job 0 0
1) "cook food"
redis> LSET job 0 "play game"
OK
redis> LRANGE job 0 0
1) "play game"
# index 超出范围
redis> LLEN list # 列表长度为 1
(integer) 1
redis> LSET list 3 'out of range'
(error) ERR index out of range
LINSERT命令
LINSERT key BEFORE|AFTER pivot value,将值value插入到列表key当中,位于值pivot之前或之后。当 pivot 不存在于列表 key 时,不执行任何操作。当 key 不存在时, key 被视为空列表,不执行任何操作。如果key 不是列表类型,返回一个错误。(多个相同pivot,只在找到的第一个前面/后面插入)
返回值:
如果命令执行成功,返回插入操作完成之后,列表的长度。
如果没有找到 pivot ,返回 -1 。
如果 key 不存在或为空列表,返回 0 。
redis> RPUSH mylist "Hello"
(integer) 1
redis> RPUSH mylist "World"
(integer) 2
redis> LINSERT mylist BEFORE "World" "There"
(integer) 3
redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"
# 对一个非空列表插入,查找一个不存在的 pivot
redis> LINSERT mylist BEFORE "go" "let's"
(integer) -1 # 失败
# 对一个空列表执行 LINSERT 命令
redis> EXISTS fake_list
(integer) 0
redis> LINSERT fake_list BEFORE "nono" "gogogog"
(integer) 0 # 失败
小结
- list实际上是一个链表,before Node after , left, right 都可以插入值
- 如果key不存在,则创建新的链表
- 如果key存在,新增内容
- 如果移除了所有值,空链表,也代表不存在
- 在两边插入或者改动值,效率最高!修改中间元素,效率相对较低消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)
Set(集合)
Hash(哈希)
Zset(有序集合Sorted Set)
浙公网安备 33010602011771号