目录

五大数据类型

Redis是一个开源(BSD许可)的,内存中的数据结构存储系统,他可以用作数据库缓存消息中间件MQ。它支持多种类型的数据结构,如 字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)与范围查询,bitmaps,hyperloglogs和地理空间(geospatial)索引半径查询。Redis内置了 复制(replication),LUA脚本(Lua scripting),LRU驱动事件(LRU eviction),事物(transactions)和不同级别的 磁盘持久化(persistence),并通过Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(high availability)。

Redis-Key

expire设置过期时间,可以用来做单点登录,热点数据设置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
127.0.0.1:6379> set name qimington
OK
127.0.0.1:6379> set age 21
OK
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists namess
(integer) 0
127.0.0.1:6379> move name 1 # 1 为当前数据库
(integer) 1
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> get age
"21"
127.0.0.1:6379> set name qimington
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> expire name 10 # 设置过期时间(秒)
(integer) 1
127.0.0.1:6379> ttl name # 查看该key的剩余有效时间
(integer) 7
127.0.0.1:6379> ttl name
(integer) 6
127.0.0.1:6379> ttl name
(integer) 5
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> type age # type查看当前key的类型
string

可以在中文官网(http://www.redis.cn/)查看命令使用方法

String

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
127.0.0.1:6379> set key1 v1	# 设置值
OK
127.0.0.1:6379> get key1	# 获得值
"v1"
127.0.0.1:6379> exists key1	# 判断某个key是否存在
(integer) 1
127.0.0.1:6379> append key1 "hello"	# 追加字符串,若该key不存在,则等价于set一个key
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> append key1 lkj4
(integer) 11
127.0.0.1:6379> get key1
"v1hellolkj4"
127.0.0.1:6379> strlen key1	# 获取字符串长度
(integer) 11

自增自减可用于浏览量的记录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views	# 自增1
(integer) 1
127.0.0.1:6379> get views
"1"
127.0.0.1:6379> decr views	# 自减1
(integer) 0
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
"-1"
127.0.0.1:6379> incrby views 10 # 自增步长数
(integer) 9
127.0.0.1:6379> incrby views 10
(integer) 19
127.0.0.1:6379> decrby views 5	#自减步长数
(integer) 14

getrange截取字符串

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> set info "hello,qimington welcome to the world"
OK
127.0.0.1:6379> get info
"hello,qimington welcome to the world"
127.0.0.1:6379> getrange info 0 3	# 截取字符串[0,3]
"hell"
127.0.0.1:6379> getrange info 0 -1	# 获取字符串
"hello,qimington welcome to the world"
127.0.0.1:6379> setrange info 1 "xx"	# 替换指定位置开始的字符串
(integer) 36
127.0.0.1:6379> get info
"hxxlo,qimington welcome to the world"

setex(set with expire)设置值并设置过期时间

setnx(set if not exist)不存在时才设置(在分布式锁中常常会使用,如乐观锁)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> setex key1 30 "qimington"	# 设置key1的值为"qimington",30秒后过期
OK
127.0.0.1:6379> ttl key1
(integer) 25
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> setnx key2 "redis"	# 如果key2不存在则创建
(integer) 1
127.0.0.1:6379> keys *
1) "key2"
127.0.0.1:6379> setnx key2 "redis"
(integer) 0
127.0.0.1:6379> keys *
1) "key2"
127.0.0.1:6379> setnx key2 "redisss"
(integer) 0
127.0.0.1:6379> keys *
1) "key2"

批量设置与批量获取

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v11 k4 v4	# 一个失败则全失败,要么一起成功要么一起失败,msetnx是一个原子性的操作
(integer) 0
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"

对象

1
2
3
4
5
6
7
8
9
127.0.0.1:6379> set user:1 {name:zhangsan,age:2}	# 设置一个"user:1"对象,值为json字符串来保存一个对象
OK
# 这里的key是一个巧妙的设计:user:{id}:{field}
127.0.0.1:6379> mset user:2:name lisi user:2:age 3
OK
127.0.0.1:6379> get user:1	# key为"user:1"
"{name:zhangsan,age:2}"
127.0.0.1:6379> get user:2:name	# key为"user:2:name"
"lisi"

getset 先get再set

1
2
3
4
5
6
7
8
127.0.0.1:6379> getset db redis	# 无值则返回nil
(nil)
127.0.0.1:6379> getset db redis
"redis"
127.0.0.1:6379> getset db mongodb
"redis"
127.0.0.1:6379> getset db mongodb
"mongodb"

小结

String类似的使用场景,value可以是字符串还可以是数字

  • 计数器
  • 统计多单位的数量 uid:923456:follow 0
  • 粉丝数
  • 对象缓存存储

List

可以实现队列阻塞队列的功能

所有的list命令都是以l开头的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
127.0.0.1:6379> lpush list1 "one"	# 将一个或者多个值插入到列表头部,即左边
(integer) 1
127.0.0.1:6379> lpush list1 "two"
(integer) 2
127.0.0.1:6379> lpush list1 "two"
(integer) 3
127.0.0.1:6379> keys *
1) "list1"
127.0.0.1:6379> lrange list1 0 -1	# 获取所有值
1) "two"
2) "two"
3) "one"
127.0.0.1:6379> lrange list1 0 1	# 获取指定区间的值
1) "two"
2) "two"
127.0.0.1:6379> rpush list1 "from right"	#将一个或者多个值插入到列表尾部,即右边
(integer) 4
127.0.0.1:6379> lrange list1 0 -1
1) "two"
2) "two"
3) "one"
4) "from right"

127.0.0.1:6379> LRANGE list1 0 -1
1) "two"
2) "two"
3) "one"
4) "from right"
127.0.0.1:6379> lpop list1 2	# 从头部移除列表两个值
1) "two"
2) "two"
127.0.0.1:6379> rpop list1	# 从尾部移除列表值,默认一个
"from right"
127.0.0.1:6379> LRANGE list1 0 -1
1) "one"

127.0.0.1:6379> lindex list1 0	# 根据列表索引下标取值
"one"
127.0.0.1:6379> llen list1	# 获取列表长度
(integer) 1
1
2
3
4
5
6
7
8
127.0.0.1:6379> lrange list1 0 -1
1) "four"
2) "four"
3) "three"
4) "two"
5) "one"
127.0.0.1:6379> lrem list1 2 four # 移除指定个数的指定key的值
(integer) 2
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
127.0.0.1:6379> LRANGE list1 0 -1
1) "hello3"
2) "hello2"
3) "hello1"
4) "hello"
127.0.0.1:6379> ltrim list1 1 2	# 通过下标截取指定的长度,并对自身做出修改
OK
127.0.0.1:6379> LRANGE list1 0 -1
1) "hello2"
2) "hello1"

rpoplpush 移除列表最后一个元素,将其添加到新列表中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
127.0.0.1:6379> lpush list "hello"
(integer) 1
127.0.0.1:6379> lpush list "hello1"
(integer) 2
127.0.0.1:6379> lpush list "hello2"
(integer) 3
127.0.0.1:6379> lpush list "hello3"
(integer) 4
127.0.0.1:6379> lpush list "hello4"
(integer) 5
127.0.0.1:6379> rpoplpush list list1
"hello"
127.0.0.1:6379> lrange list 0 -1
1) "hello4"
2) "hello3"
3) "hello2"
4) "hello1"
127.0.0.1:6379> lrange list1 0 -1
1) "hello"

lset将列表中指定下标的值替换为另外一个值,相当于更新操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> exists list
(integer) 0
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 newvalue
OK
127.0.0.1:6379> lrange list 0 0
1) "newvalue"
127.0.0.1:6379> lset list 1 newvalue
(error) ERR index out of range

linsert将某个具体的value插入列表中某个具体的元素的前面或者后面

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
127.0.0.1:6379> lpush list value
(integer) 1
127.0.0.1:6379> lpush list value1
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "value1"
2) "value"
127.0.0.1:6379> linsert list before "value1" "before"
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "before"
2) "value1"
3) "value"
127.0.0.1:6379> linsert list after "value1" "after"
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "before"
2) "value1"
3) "after"
4) "value"

小结

  • list实际上是一个链表,before,after,left,right都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有值,空链表,也代表不存在!
  • 在两边插入值或者改动值,效率最高,如果是中间元素,相对来说效率会低一些

Set

set中的值是不能重复的,且是无序的

sadd, smembers, sismember, scard

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
127.0.0.1:6379> sadd myset "hello"	# set集合中添加值
(integer) 1
127.0.0.1:6379> sadd myset "world" "qimignton"
(integer) 2
127.0.0.1:6379> smembers myset	# 查看指定set中的现有值
1) "world"
2) "qimignton"
3) "hello"
127.0.0.1:6379> sismember myset "hi"	# 判断某一个值是不是在set集合中
(integer) 0
127.0.0.1:6379> sismember myset "hello"
(integer) 1
127.0.0.1:6379> scard myset	# 查看set集合中内容元素的个数
(integer) 3

srem移除set集合中的指定元素

1
2
3
4
5
6
7
8
9
127.0.0.1:6379> smembers myset
1) "world"
2) "qimignton"
3) "hello"
127.0.0.1:6379> srem myset "hello"
(integer) 1
127.0.0.1:6379> smembers myset
1) "world"
2) "qimignton"

spop随机删除set中的若干个值,默认1个

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
127.0.0.1:6379> smembers myset
1) "welcome"
2) "hello"
3) "the"
4) "place"
5) "world"
6) "qimington"
7) "to"
127.0.0.1:6379> spop myset 2
1) "world"
2) "welcome"
127.0.0.1:6379> smembers myset
1) "the"
2) "place"
3) "qimington"
4) "to"
5) "hello"

srandmember随机获取set集合中的若干个值(默认为1)

1
2
3
4
5
127.0.0.1:6379> srandmember myset
"world"
127.0.0.1:6379> srandmember myset 2
1) "world"
2) "hello"

smove实现集合间元素移动

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> smembers myset
1) "the"
2) "place"
3) "qimington"
4) "to"
5) "hello"
127.0.0.1:6379> smembers myset2
1) "set2"
127.0.0.1:6379> smove myset myset2 "the"	# 将一个指定的值移动到另外一个set集合
(integer) 1
127.0.0.1:6379> smembers myset
1) "place"
2) "qimington"
3) "to"
4) "hello"
127.0.0.1:6379> smembers myset2
1) "the"
2) "set2"

集合的sinter(交)、sunion(并)、sdiff(差)操作

sinter(交)可以实现共同用户的查找,或者二度好友(即好友推荐)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> smembers set1
1) "world"
2) "qimington"
3) "hello"
127.0.0.1:6379> smembers set2
1) "moto"
2) "qimington"
3) "hello"
127.0.0.1:6379> sdiff set1 set2	# 差集
1) "world"
127.0.0.1:6379> sinter set1 set2	# 交集
1) "qimington"
2) "hello"
127.0.0.1:6379> sunion set1 set2	# 并集
1) "moto"
2) "qimington"
3) "hello"
4) "world"

Hash

Map集合,即key–。本质和String类型没有太大区别,还是简单的key-value

hset, hget, hmget, hgetall, hdel, hlen, hexists, hkeys, hvals

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
127.0.0.1:6379> hset myhash field1 "qimington"
(integer) 1
127.0.0.1:6379> hget myhash field1
"qimington"
127.0.0.1:6379> hmset myhash field1 hello field2 world
OK
127.0.0.1:6379> hmget myhash field1 field2	# 获取多个字段
1) "hello"
2) "world"
127.0.0.1:6379> hgetall myhash	# 获取所有数据
1) "field1"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> hdel myhash field1	# 删除hash指定的key字段,对应的value值也就消失了
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field2"
2) "world"
127.0.0.1:6379> hlen myhash	# 查询hash表的字段数量,这里只有一个键值对
(integer) 1
127.0.0.1:6379> hexists myhash field1	# 判断hash中指定字段是否存在
(integer) 0
127.0.0.1:6379> hexists myhash field2
(integer) 1
127.0.0.1:6379> hkeys myhash	# 只获取所有的field
1) "field2"
127.0.0.1:6379> hvals myhash	# 只获取所有的value
1) "world"

hincrby

1
2
3
4
5
6
127.0.0.1:6379> hset myhash field 5
(integer) 1
127.0.0.1:6379> hincrby myhash field 1
(integer) 6
127.0.0.1:6379> hincrby myhash field -1
(integer) 5

hsetnx

1
2
3
4
127.0.0.1:6379> hsetnx myhash field1 hello	# 如果不存在则可以设置,否则不可以设置
(integer) 1
127.0.0.1:6379> hsetnx myhash field1 hello
(integer) 0

小结

  • hash变更的数据user name age,尤其是用户信息之类的,经常变动的信息!hash更加适合于对象的存储,String更加适合字符串的存储

    hset user:1 name qimington

Zset(有序集合)

在set的基础上,增加了一个值,sadd k1 v1=> zadd k1 score1 v1

zadd, zrange

1
2
3
4
5
6
7
8
127.0.0.1:6379> zadd myset 1 one
(integer) 1
127.0.0.1:6379> zadd myset 1 two 3 three
(integer) 2
127.0.0.1:6379> zrange myset 0 -1
1) "one"
2) "two"
3) "three"

zrangebyscore 升序排序 zrevrangebyscore降序排列

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
127.0.0.1:6379> zadd salary 2500 xiaohong	# 添加三个
(integer) 1
127.0.0.1:6379> zadd salary 5000 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 500 lisi
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "lisi"
2) "xiaohong"
3) "zhangsan"
# ZRANGEBYSCORE key min max [withscores]
127.0.0.1:6379> ZRANGEBYSCORE salary -inf inf	# 显示全部用户 从小到大
1) "lisi"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf inf withscores	# 显示全部用户,并显示详细信息
1) "lisi"
2) "500"
3) "xiaohong"
4) "2500"
5) "zhangsan"
6) "5000"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf 2500 withscores	# 显示小于等于2500的升序
1) "lisi"
2) "500"
3) "xiaohong"
4) "2500"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf (2500 withscores	# 显示小于2500的升序
1) "lisi"
2) "500"
# ZREVRANGEBYSCORE key max min [withscores]
127.0.0.1:6379> ZREVRANGEBYSCORE salary inf -inf withscores	# 显示全部用户 从大到小
1) "zhangsan"
2) "5000"
3) "xiaohong"
4) "2500"
5) "lisi"
6) "500"

rem移除指定元素 zcard获取个数 zcount计数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> zrange salary 0 -1
1) "lisi"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> zrem salary xiaohong
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "lisi"
2) "zhangsan"
127.0.0.1:6379> zcard salary
(integer) 2
127.0.0.1:6379> zrangebyscore salary -inf inf withscores
1) "lisi"
2) "500"
3) "zhangsan"
4) "5000"
127.0.0.1:6379> zcount salary 0 2000	# 查询再0与2000之间的值的个数
(integer) 1

小结

set排序,存储班级成绩表,工资表排序

  1. 重要消息
  2. 带权重的判断
  3. 排行榜,Top N测试