redis的数据结构与命令
以下部分文档,摘自51cto讲师:汤小洋
redis提供五种数据类型:string,hash,list,set及zset(sorted set)。
Redis数据就是以key value形式来存储的,key只能是字符串类型,value可以是以下五种类型:String、List、 Set、SortedSets、Hash
五种数据类型的添加读取如下:
127.0.0.1:6379> set myset name string类型添加
OK
127.0.0.1:6379> get myset string类型读取
"name"
127.0.0.1:6379> lpush mylist a b c d list类型添加
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1 list类型读取
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> sadd myset2 a b c d e set类型添加
(integer) 5
127.0.0.1:6379> SMEMBERS myset2 set类型读取
1) "d"
2) "b"
3) "a"
4) "c"
5) "e"
127.0.0.1:6379> zadd myzset 10 one 20 two 30 three 40 four z-set类型添加
(integer) 4
127.0.0.1:6379> zrange myzset 0 -1 z-set类型读取
1) "one"
2) "two"
3) "three"
4) "four"
127.0.0.1:6379> hset myhash username tom hash类型添加
(integer) 1
127.0.0.1:6379> hget myhash username hash类型读取
"tom"
127.0.0.1:6379>
如下图所示:
一、String(字符串)
字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任 何格式的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度 是512M。
常用命令
select 0 切换到第一个数据库,默认有16个数据库
flushdb 清空数据库
set key value 设置一个键key 并存入值
get key 获取一个键key,返回键中的值
strlen key 获取一个键key,返回键中的值的长度
exists key 判断一个键key是否存在,如果存在返回1,否则返回0
append key value 向指定的键追加值,如果该键不存在,会自动创建并返回值的长度,如果该键存在,向该键的值后追加值,并返回追加后值的长度
set key value ex 秒数 设置一个键的过期时间,单位为秒
set key value px 毫秒数 设置一个键的过期时间,单位为毫秒 注意:ex 和px 不能同时使用
ttl key 检测一个键的过期状态 如果过期返回-2,否则返回快过期的实时时间
incr key 设置整型key,每次递增1
decr key 设置整型key,每次递减1
incrby key 10 设置整型key,递增10,即步长
decrby key 10 设置整型key,递减10,即步长
del key 删除指定的key
getset name tom 获取一个key name 并重新设置value为tom
setex age 30 20 设置一个key为age,30秒过期,value为20
ttl age 查看key的过期时间的状态
127.0.0.1:6379> setnx name jack 设置一个key为name ,value为jack,如果key存在不设置返回0,只有当不存在的时候才设置返回1
(integer) 0
127.0.0.1:6379> setnx address suzhou 设置一个key为address ,value为suzhou,如果key存在不设置返回0,只有当不存在的时候才设置返回1
(integer) 1
setrange key offset value 重新设置已有key指定位置的值
getrange key start end 获取指定位置key的值
mset key1 key1value key2 key2value........ 同时设置多个key和值
mget key1 key2....同时获取多个key的值
msetnx key1 key1value key2 key2value........ 同时设置多个key和值,如果设置其中的某个key已存在,返回0,表示成功,如果要设置的多个key不存在,返回1,表示成功
二、List类型
lpush key value [value ...] 从左到右依次插入数据,靠右排列,返回插入后的元素个数
例子:
127.0.0.1:6379> lpush mykey a b c d e
(integer) 5
lrange key start top 查询列表范围内的指定元素,
例子:获取所有元素,0和-1代表从0开始到最后一个元素(即查询所有)
127.0.0.1:6379> lrange mykey 0 -1
1) "e"
2) "d"
3) "c"
4) "b"
5) "a"
lpushx key value 向指定的key中插入数据,如果该key存在,返回该key的元素最新个数,否则返回0
例子:
127.0.0.1:6379> lpushx mykey f
(integer) 6
127.0.0.1:6379> lpushx mykey f
(integer) 7
127.0.0.1:6379> lpushx mykey1 a
(integer) 0
lpop key 弹出最后插入的一个元素
例子:
127.0.0.1:6379> lpop mykey
"f"
llen key 返回该key的元素的个数
例子:
127.0.0.1:6379> llen mykey
(integer) 6
lrem key count value 移除key中的指定数量的元素,成功返回1
例子:移除2个f元素
127.0.0.1:6379> lrem mykey 2 f
(integer) 1
lindex key index 获取key中指定索引的值
例子:获取索引为2的元素
127.0.0.1:6379> lindex mykey 2
"c"
lset key index value 向key中的指定索引未知插入值
例子:设置索引为0元素的新值为o
127.0.0.1:6379> lset mykey 0 o
OK
127.0.0.1:6379> lrange mykey 0 -1
1) "o"
2) "d"
3) "c"
4) "b"
5) "a"
ltrim mykey start top 移除key中指定索引以外的所有元素,只保留指定范围内的元素
例子:移除索引0-索引3范围以外的所有元素
127.0.0.1:6379> ltrim mykey 0 3
OK
127.0.0.1:6379> lrange mykey 0 -1
1) "o"
2) "d"
3) "c"
4) "b"
linsert key brefore|after pivot value 向 key中指定元素之前或者之后插入新的元素,返回最新元素的个数
例子:在元素b之前插入j
127.0.0.1:6379> linsert mykey before b j
(integer) 5
127.0.0.1:6379> lrange mykey 0 -1
1) "o"
2) "d"
3) "c"
4) "j"
5) "b"
例子:在元素b之后插入k
127.0.0.1:6379> linsert mykey after b k
(integer) 6
127.0.0.1:6379> lrange mykey 0 -1
1) "o"
2) "d"
3) "c"
4) "j"
5) "b"
6) "k"
rpush key value..... 从左到右依次插入,然后靠左列,返回插入元素的个数
例子:
127.0.0.1:6379> rpush mykey a b c d
(integer) 4
127.0.0.1:6379> lrange mykey 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
rpushx key value 向指定key中插入新的元素,如果该key 存在,返回key中最新的元素个数 ,否则返回0,插入失败
例如:向mykey2中插入a,mykey2存在,并返回最新元素个数
127.0.0.1:6379> rpushx mykey2 a
(integer) 2
127.0.0.1:6379> lrange mykey2 0 -1
1) "f"
2) "a"
127.0.0.1:6379> keys *
1) "mykey2"
2) "mykey"
3) "mykey1"
例如:向mykey3中插入a,mykey3不存在,返回0
例子:
127.0.0.1:6379> rpushx mykey3 a
(integer) 0
rpoplpush 弹出右边最后添加的一个元素,再从左边插入,左进右出
例如:弹出右边最后添加的一个元素f,然后从左边插入
127.0.0.1:6379> rpoplpush mykey mykey
"f"
127.0.0.1:6379> lrange mykey 0 -1
1) "f"
2) "a"
3) "b"
4) "c"
5) "d"
rpop 弹出右边最后添加的一个元素
127.0.0.1:6379> rpop mykey
"d"
三、Set类型
在Redis中,我们可以将Set类型看作为没有排序的字符集合,也可以在该类型的数据值上执行添加、删除或判 断某一元素是否存在等操作。Set可包含的最大元素数量是4294967295。
和List类型不同的是,Set集合中不允许出现重复的元素,这一点和Java中的set容器是完全相同的。换句话 说,如果多次添加相同元素,Set中将仅保留该元素的一份拷贝。和List类型相比,Set类型在功能上还存在着一个 非常重要的特性,即在服务器端完成多个Sets之间的聚合计算操作,如unions并、intersections交和differences 差。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销。
sadd key menber 添加数据,返回元素的个数
例子:
127.0.0.1:6379> sadd myset a b c d
(integer) 4
SMEMBERS key 查看数据
例子:
127.0.0.1:6379> SMEMBERS myset
1) "d"
2) "b"
3) "a"
4) "c"
插入重复数据后,只执行保留新的成员
例子:
127.0.0.1:6379> sadd myset c e
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "c"
2) "e"
3) "a"
4) "b"
5) "d"
SISMEMBER key mebber 验证元素是否存在 ,如果存在返回1
例子:
127.0.0.1:6379> SISMEMBER myset a
(integer) 1
scard key 返回元素的个数
例子:
127.0.0.1:6379> scard myset
(integer) 5
127.0.0.1:6379>
SRANDMEMBER myset 返回集合中随机的一个元素
例子:
127.0.0.1:6379> SRANDMEMBER myset
"c"
spop myset 弹出集合中随机的一个元素,该元素弹出后会从集合中移除
例子:
127.0.0.1:6379> spop myset
"d"
127.0.0.1:6379> SMEMBERS myset
1) "e"
2) "a"
3) "b"
4) "c"
srem myset a 从集合中移除指定元素a,如果元素存在,执行成功后,返回1
例子:
127.0.0.1:6379> srem myset a
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "e"
2) "b"
3) "c"
SMOVE myset myset2 b 移动myset集合中的元素b到另一个集合myset2中,如果myset2不存在,会自动创建,执行成功返回1
例子:
127.0.0.1:6379> SMOVE myset myset2 b
(integer) 1
127.0.0.1:6379> keys *
1) "myset"
2) "myset2"
127.0.0.1:6379> SMEMBERS myset2
1) "b"
如果移动时元素不存在,返回0
127.0.0.1:6379> SMOVE myset myset2 b
(integer) 0
127.0.0.1:6379>
sdiff myset myset2 myset3 获得多个集合中比对的差异结果
127.0.0.1:6379> sadd myset a b c d
(integer) 4
127.0.0.1:6379> sadd myset2 a
(integer) 1
127.0.0.1:6379> sadd myset3 a c e
(integer) 3
127.0.0.1:6379> sdiff myset myset2 myset3
1) "b"
2) "d"
SDIFFSTORE diffkey myset myset2 myset3 获得差异结果后,将结果存储到diffkey集合中,返回差异结果元素的个数,如果diffkey集合不存在,直接创建
127.0.0.1:6379> SDIFFSTORE diffkey myset myset2 myset3
(integer) 2
127.0.0.1:6379> SMEMBERS diffkey
1) "b"
2) "d"
SINTER myset myset2 myset3 获取多个集合中交集的元素
127.0.0.1:6379> SINTER myset myset2 myset3
1) "a"
SINTERSTORE interkey myset myset2 myset3 获得多个集合中交集的元素后,保存到interkey集合中,返回交集结果元素的个数,如果interkey集合不存在,直接创建
127.0.0.1:6379> SINTERSTORE interkey myset myset2 myset3
(integer) 1
127.0.0.1:6379> SMEMBERS interkey
1) "a"
127.0.0.1:6379>
SUNION myset myset2 myset3 获取多个集合中并集元素
127.0.0.1:6379> SUNION myset myset2 myset3
1) "e"
2) "b"
3) "a"
4) "c"
5) "d"
SUNIONSTORE unionkey myset myset2 myset3 获得多个集合中并集的元素后,保存到unionkey集合中,返回交集结果元素的个数,如果unionkey集合不存在,直接创建
127.0.0.1:6379> SUNIONSTORE unionkey myset myset2 myset3
(integer) 5
127.0.0.1:6379> SMEMBERS unionkey
1) "e"
2) "b"
3) "a"
4) "c"
5) "d"
四、SortedSets类型
SortedSets和Sets类型极为相似,也称为Zset,它们都是字符串的集合,都不允许重复的成员出现在一个Set 中。它们之间的主要差别是SortedSets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为 集合中的成员进行从小到大的排序(默认)。然而需要额外指出的是,尽管SortedSets中的成员必须是唯一的,但 是分数(score)却是可以重复的。
在SortedSet中添加、删除或更新一个成员都是非常快速的操作。由于SortedSets中的成员在集合中的位置是 有序的,因此,即便是访问位于集合中部的成员也仍然是非常高效的。事实上,Redis所具有的这一特征在很多其它 类型的数据库中是很难实现的,换句话说,在该点上要想达到和Redis同样的高效,在其它数据库中进行建模是非常 困难的。
zadd myzset 10 yuwen 添加分为一个分数为10的yuwen元素到myzset集合中,返回添加成功的个数
127.0.0.1:6379> zadd myzset 10 yuwen
(integer) 1
zadd myzset 10 mathe 50 english 添加多个分数的元素到myzset集合中,返回添加成功的个数
127.0.0.1:6379> zadd myzset 10 mathe 50 english
(integer) 2
zrange myzset 0 -1 withscores 查询所有元素,withscores表示返回每个成员和分数,否则只显示成员,例如:mathe、yuwen、english
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "mathe"
2) "10"
3) "yuwen"
4) "10"
5) "english"
6) "50"
zcard myzset 返回集合中元素的个数
127.0.0.1:6379> zcard myzset
(integer) 3
zrank myzset english 返回集合中指定元素索引位置
127.0.0.1:6379> zrank myzset english
(integer) 2
zcount myzset 20 50 返回集合中符合大于等于分数20并且小于等于50的分数元素
127.0.0.1:6379> zcount myzset 20 50
(integer) 1
zrem myzset mathe yuwen 移除集合中的指定元素,返回移除成功的元素个数
127.0.0.1:6379> zrem myzset mathe yuwen
(integer) 2
zscore myzset english 获取集合中指定元素的分数,返回结果以字符串形式显示
127.0.0.1:6379> zscore myzset english
"50"
zincrby myzset 30 english 设置集合中的english元素的分数步增长为30,返回增长后的分数
127.0.0.1:6379> zincrby myzset 30 english
"80"
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "english"
2) "80"
ZRANGEBYSCORE myzset 60 80 获取集合中大于等于60并且小于等于80的元素信息
127.0.0.1:6379> ZRANGEBYSCORE myzset 60 80
1) "mathe"
2) "english"
ZRANGEBYSCORE myzset -inf +inf withscores limit 0 5 -inf 从第一个元素开始 +inf到最后一个元素,limit类似于mysql的limit 取位置索引0开始 后面5个元素
127.0.0.1:6379> ZRANGEBYSCORE myzset -inf +inf withscores limit 0 5
1) "yuwen"
2) "30"
3) "mathe"
4) "60"
5) "english"
6) "80"
ZREMRANGEBYSCORE myzset 30 60 移除集合中大于等于30并且小于等于60的元素信息,返回执行成功的个数
127.0.0.1:6379> ZREMRANGEBYSCORE myzset 30 60
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1
1) "english"
127.0.0.1:6379>
127.0.0.1:6379> zadd myzset 30 yuwen 60 mathe
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1
1) "yuwen"
2) "mathe"
3) "english"
ZREMRANGEBYSCORE myzset 30 60 移除集合索引从0-2的元素信息,返回执行成功的个数
127.0.0.1:6379> ZREMRANGEBYRANK myzset 0 2
(integer) 3
127.0.0.1:6379> zrange myzset 0 -1
(empty list or set)
ZREVRANGE myzset 0 -1 withscores 获取集合中的所有元素(包含分数),按索引从高到低的方式显示
127.0.0.1:6379> ZREVRANGE myzset 0 -1 withscores
1) "four"
2) "40"
3) "three"
4) "30"
5) "two"
6) "20"
7) "one"
8) "10"
ZREVRANGEBYSCORE myzset 40 20 withscores 获取集合中分数小于等于40并且大于等于20的元素信息(包含分数)
127.0.0.1:6379> ZREVRANGEBYSCORE myzset 40 20 withscores
1) "four"
2) "40"
3) "three"
4) "30"
5) "two"
6) "20"
ZREVRANGEBYSCORE myzset 40 20 withscores limit 0 1 获取集合中分数小于等于40并且大于等于20的元素信息(包含分数),只取索引从0 开始,后面的1个元素信息
127.0.0.1:6379> ZREVRANGEBYSCORE myzset 40 20 withscores limit 0 1
1) "four"
2) "40"
127.0.0.1:6379> ZREVRANGEBYSCORE myzset 40 20 withscores limit 0 2
1) "four"
2) "40"
3) "three"
4) "30"
ZREVRANK myzset three 获取集合中three元素,返回该元素的索引位置,由于是从高到低排序,所以three元素索引为1
127.0.0.1:6379> ZREVRANK myzset three
(integer) 1
127.0.0.1:6379>
SortedSets应用范围
1. 可以用于大型在线游戏的积分排行榜。每当玩家的分数发生变化时,可以执行ZADD命令更新玩家的分 数,此后再通过ZRANGE命令获取积分TOP 10的用户信息。当然我们也可以利用ZRANK命令通过 username来获取玩家的排行信息。最后我们将组合使用ZRANGE和ZRANK命令快速的获取和某个玩家积 分相近的其他用户的信息。
2. SortedSets类型还可用于构建索引数据。
五、Hash(哈希)类型
127.0.0.1:6379> hset myset username tom
(integer) 1
hget myset username 获取集合myset中的键username的值
127.0.0.1:6379> hget myset username
"tom"
HEXISTS myset username 判读集合myset中的键username是否存在,存在返回1,否则返回0
127.0.0.1:6379> HEXISTS myset username
(integer) 1
hlen myset 返回集合myset的字段数量
127.0.0.1:6379> hlen myset
(integer) 1
hlen myset 删除集合myset的key:username,删除成功返回1
127.0.0.1:6379> hdel myset username
(integer) 1
hsetnx myset username tom 如果集合myset中的key:username不存在,执行插入返回1,如果存在,不执行插入,返回0
127.0.0.1:6379> hsetnx myset username tom
(integer) 1
127.0.0.1:6379> hsetnx myset username tom
(integer) 0
127.0.0.1:6379> hset myset age 20
(integer) 1
HINCRBY myset age 10 设置集合myset的key:age步增长为10,返回增长后的值
127.0.0.1:6379> HINCRBY myset age 10
(integer) 30
hmset myset address suzhou phone 12345 一次往集合myset中添加多个key和值
127.0.0.1:6379> hmset myset address suzhou phone 12345
OK
hmget myset username address phone 一次获取集合myset中的多个key,返回key的值
127.0.0.1:6379> hmget myset username address phone
1) "tom"
2) "suzhou"
3) "12345"
hgetall myset 获取集合myset中的所有key 和value
127.0.0.1:6379> hgetall myset
1) "username"
2) "tom"
3) "age"
4) "30"
5) "address"
6) "suzhou"
7) "phone"
8) "12345"
hkeys myset 获取集合myset中的所有key
127.0.0.1:6379> hkeys myset
1) "username"
2) "age"
3) "address"
4) "phone"
hkeys myset 获取集合myset中的所有value
127.0.0.1:6379> hvals myset
1) "tom"
2) "30"
3) "suzhou"
4) "12345"
keys pattern
获取所有匹配pattern参数的Keys。需要说明的是,在我们的正常操作中应该尽量避免对该命令的调 用,因为对于大型数据库而言,该命令是非常耗时的,对Redis服务器的性能打击也是比较大的。 pattern支持globstyle的通配符格式,如*表示任意一个或多个字符,?表示任意字符,[abc]表示方括 号中任意一个字母。
del key [key...]
从数据库删除中参数中指定的keys,如果指定键不存在,则直接忽略。
exists key
判断指定键是否存在。
move key db
将当前数据库中指定的键Key移动到参数中指定的数据库中。如果该Key在目标数据库中已经存在, 或者在当前数据库中并不存在,该命令将不做任何操作并返回0。
rename key newkey
为指定指定的键重新命名,如果参数中的两个Keys的命令相同,或者是源Key不存在,该命令都会返 回相关的错误信息。如果newKey已经存在,则直接覆盖。
renamenx key newkey
如果新值不存在,则将参数中的原值修改为新值。其它条件和RENAME一致。
persist key
如果Key存在过期时间,该命令会将其过期时间消除,使该Key不再有超时,而是可以持久化存储。
expire key seconds
该命令为参数中指定的Key设定超时的秒数,在超过该时间后,Key被自动的删除。如果该Key在超 时之前被修改,与该键关联的超时将被移除。
expireat key timestamp
该命令的逻辑功能和EXPIRE完全相同,唯一的差别是该命令指定的超时时间是绝对时间,而不是相 对时间。该时间参数是Unix timestamp格式的,即从1970年1月1日开始所流经的秒数。
ttl key 获取该键所剩的超时描述。
randomkey 从当前打开的数据库中随机的返回一个Key。
type key 获取与参数中指定键关联值的类型,该命令将以字符串的格式返回。