redis的数据结构与命令

Posted 将哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis的数据结构与命令相关的知识,希望对你有一定的参考价值。

 

 

以下部分文档,摘自51cto讲师:汤小洋

 

redis提供五种数据类型:string,hash,list,set及zset(sorted set)。

 

Redis数据就是以key­ value形式来存储的,key只能是字符串类型,value可以是以下五种类型:String、List、 Set、Sorted­Sets、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类型

 

在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部 (left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中的数据元素均被移除,那么该键也会从数据库中删除。List中可以包含的最大元素数量是4294967295。
 
 
从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。
 
 

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  获得多个集合中比对的差异结果

#先将myset和myset2进行比较,a、b和d三个成员是两者之间的差异成员,然后再用这个结果继续和 myset3进行差异比较,b和d是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"

 


四、Sorted­Sets类型

Sorted­Sets和Sets类型极为相似,也称为Zset,它们都是字符串的集合,都不允许重复的成员出现在一个Set 中。它们之间的主要差别是Sorted­Sets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为 集合中的成员进行从小到大的排序(默认)。然而需要额外指出的是,尽管Sorted­Sets中的成员必须是唯一的,但 是分数(score)却是可以重复的。

在Sorted­Set中添加、删除或更新一个成员都是非常快速的操作。由于Sorted­Sets中的成员在集合中的位置是 有序的,因此,即便是访问位于集合中部的成员也仍然是非常高效的。事实上,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>

 

 

Sorted­Sets应用范围

1. 可以用于大型在线游戏的积分排行榜。每当玩家的分数发生变化时,可以执行ZADD命令更新玩家的分 数,此后再通过ZRANGE命令获取积分TOP 10的用户信息。当然我们也可以利用ZRANK命令通过 username来获取玩家的排行信息。最后我们将组合使用ZRANGE和ZRANK命令快速的获取和某个玩家积 分相近的其他用户的信息。

2. Sorted­Sets类型还可用于构建索引数据。 

 

 

五、Hash(哈希)类型

 

可以将Redis中的Hash类型看成具有String Key和String Value的map容器。所以该类型非常适合于存储值对象 的信息。如Username、Password和Age等。如果Hash中包含很少的字段,那么该类型的数据也将仅占用很少的磁 盘空间。每一个Hash可以存储4294967295个键值对。
 
 
hset myset username tom  设置一个集合myset ,添加键username,值tom,返回添加成功的元素个数

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"

 

 
 
 
 
 key操作命令
 

keys pattern

获取所有匹配pattern参数的Keys。需要说明的是,在我们的正常操作中应该尽量避免对该命令的调 用,因为对于大型数据库而言,该命令是非常耗时的,对Redis服务器的性能打击也是比较大的。 pattern支持glob­style的通配符格式,如*表示任意一个或多个字符,?表示任意字符,[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   获取与参数中指定键关联值的类型,该命令将以字符串的格式返回。

 
 
 
 

 

 

 

以上是关于redis的数据结构与命令的主要内容,如果未能解决你的问题,请参考以下文章

Redis中的数据结构与常用命令

非关系型数据库Redis简介常用命令与优化

redis的数据结构与命令

Redis 数据备份与恢复

Redis 数据备份与恢复

Redis数据库——Redis简介部署及常用命令