五大数据类型

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

Redis-Key

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> set name hello
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"hello"
127.0.0.1:6379> EXPIRE name 10 # 设置key的过期时间,单位是秒
(integer) 1
127.0.0.1:6379> ttl name #查看当前key的剩余时间
(integer) -2
127.0.0.1:6379> type name # 查看当前key的类型
string

String

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
127.0.0.1:6379> set key1 v1 # 设置值
OK
127.0.0.1:6379> get key1 # 获得值
"v1"
127.0.0.1:6379> keys * #获得所有的key
1) "key1"
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> STRLEN key1 # 获取字符串的长度
(integer) 7
127.0.0.1:6379> APPEND key1 ",world"
(integer) 13
127.0.0.1:6379> STRLEN key1
(integer) 13
127.0.0.1:6379> get key1
"v1hello,world"
##########################################################
# i++
# 步长
127.0.0.1:6379>
127.0.0.1:6379> set view 0
OK
127.0.0.1:6379> get views
(nil)
127.0.0.1:6379> get view
"0"
127.0.0.1:6379> INCR view # 自增1
(integer) 1
127.0.0.1:6379> INCR view
(integer) 2
127.0.0.1:6379> DECR view # 自减1
(integer) 1
127.0.0.1:6379> DECR view
(integer) 0
127.0.0.1:6379> get view
"0"
127.0.0.1:6379> INCRBY view 10 # 可以设置步长,指定增量
(integer) 10
127.0.0.1:6379> INCRBY view 10
(integer) 20
127.0.0.1:6379> DECRBY view 10
(integer) 10

#############################################
127.0.0.1:6379> set key1 "hello,world" # 设置key1的值
OK
127.0.0.1:6379> set key1
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> get key1
"hello,world"
127.0.0.1:6379> GETRANGE key1 0 3 # 截取字符串 [0,3]
"hell"
127.0.0.1:6379> GETRANGE key1 0 -1 # 获取全部的字符串 和 get key是一样的
"hello,world"

# 替换
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg"
127.0.0.1:6379> SETRANGE key2 1 xx # 替换指定位置开始的字符串
(integer) 7
127.0.0.1:6379> get key2
"axxdefg"
##################################################################
# setex (set with expire) # 设置过期时间
# setnx (set if not exist) # 不存在再设置 (在分布式锁中会经常使用)

127.0.0.1:6379> SETEX key3 30 "hello" # 设置key3 的值为 hello,30秒后过期
OK
127.0.0.1:6379> ttl key3
(integer) 27
127.0.0.1:6379> get key3
"hello"
127.0.0.1:6379> setnx mykey "redis" # 如果mykey 不存在,创建mykey
(integer) 1
127.0.0.1:6379> keys *
1) "mykey"
2) "key1"
3) "key2"
127.0.0.1:6379> setnx mykey "MongoDB" # 如果mykey存在,创建失败
(integer) 0
127.0.0.1:6379> get mykey
"redis"
#####################################################################
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3 # 同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4 # msetnx 是一个原子性的操作,要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> get k4
(nil)

# 对象
set user:1 {name:zhangsan,age:3} #设置一个user:1 对象 值为json字符来保存一个对象!

# 这里的key是一个巧妙的设计 : user:{id}:{filed} , 如此设计在Redis中是完全ok

127.0.0.1:6379>
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"

#############################################################
getset # 先get然后再set

127.0.0.1:6379> getset db redis # 如果不存在值,则返回nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongoDB # 如果存在值,获取原来的值,并设置新的值
"redis"
127.0.0.1:6379> get db
"mongoDB"

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#############################################################
127.0.0.1:6379> LPUSH list one # 将一个值或者多个值,插入到列表头部(左)
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1 # 获取list中的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1 # 通过区间获取具体的值
1) "three"
2) "two"
127.0.0.1:6379> RPUSH list right # 将一个值或者多个值,插入到列表尾部(右)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"

############################################################
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> LPOP list # 移除list的第一个元素
"three"
127.0.0.1:6379> rpop list # 移除list的最后一个元素
"right"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"

############################################################
127.0.0.1:6379> LINDEX list 1
"one"
127.0.0.1:6379> LINDEX list 0
"two"

#############################################################
127.0.0.1:6379> LPUSH list one
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LLEN list # 返回列表的长度
(integer) 3

############################################################
移除指定的值
127.0.0.1:6379> LREM list 1 one # 移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> LREM list 2 three
(integer) 2
127.0.0.1:6379> LRANGE list 0 -1
1) "two"

############################################################
trim 修剪。

127.0.0.1:6379> RPUSH mylist "hello1"
(integer) 1
127.0.0.1:6379> RPUSH mylist "hello2"
(integer) 2
127.0.0.1:6379> RPUSH mylist "hello3"
(integer) 3
127.0.0.1:6379> LTRIM mylist 1 2 # 通过下表截取指定的长度
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello2"
2) "hello3"

############################################################
rpoplpush # 移除列表的最后一个元素,将他移动到新的列表中

127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
127.0.0.1:6379> RPUSH mylist "hello1"
(integer) 2
127.0.0.1:6379> RPUSH mylist "hello2"
(integer) 3
127.0.0.1:6379> RPOPLPUSH mylist mytoherlist # 移除列表的最后一个元素,将他移动到新的列表中
"hello2"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "hello1"
127.0.0.1:6379> LRANGE mytoherlist 0 -1
1) "hello2"

############################################################
lset 将列表中指定下标的值替换为另一个值,更新操作
127.0.0.1:6379> EXISTS list # 判断这个列表是否存在
(integer) 0
127.0.0.1:6379> lset list 0 item # 如果不存在列表我们去更新就会报错
(error) ERR no such key
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 item # 如果存在,更新当前下标的值
OK
127.0.0.1:6379> LRANGE list 0 0
1) "item"
127.0.0.1:6379> lset list 1 other # 如果不存在,则会报错
(error) ERR index out of range
############################################################
linsert # 将某个具体的value插入到列表中某个元素的前面或者后面
127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
127.0.0.1:6379> RPUSH mylist "world"
(integer) 2
127.0.0.1:6379> LINSERT mylist before "world" "other"
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379> LINSERT mylist after world new
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "other"
3) "world"
4) "new"

小结

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

Set(集合)

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
42
43
44
45
46
47
48
49
50
51
############################################################
127.0.0.1:6379> sadd myset "hello" # set集合中添加值
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> sadd myset "one two"
(integer) 1
127.0.0.1:6379> SMEMBERS myset # 查看指定set的所有值
1) "one two"
2) "hello"
3) "world"
127.0.0.1:6379> SISMEMBER myset hello # 判断某一个值是否在set中
(integer) 1
127.0.0.1:6379> SISMEMBER myset gkd
(integer) 0

############################################################
127.0.0.1:6379> SCARD myset # 获取set集合中的内容元素个数
(integer) 3

############################################################
127.0.0.1:6379> SREM myset hello # 移除set集合中的指定元素
(integer) 1
127.0.0.1:6379> SCARD myset
(integer) 2
127.0.0.1:6379> SMEMBERS myset
1) "one two"
2) "world"

############################################################
127.0.0.1:6379> SMEMBERS myset
1) "one two"
2) "world"
127.0.0.1:6379> SRANDMEMBER myset # 随机抽选出一个元素
"one two"
127.0.0.1:6379> SRANDMEMBER myset
"one two"
127.0.0.1:6379> SRANDMEMBER myset
"world"

############################################################
随机删除key

127.0.0.1:6379> SMEMBERS myset
1) "one two"
2) "world"
127.0.0.1:6379> SPOP myset # 随机删除一些set集合中的元素
"one two"
127.0.0.1:6379> SMEMBERS myset
1) "world"

Hash

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

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
42
43
44
127.0.0.1:6379> HSET myhash field1 hello		# set 一个具体 key-value
(integer) 1
127.0.0.1:6379> HGET myhash field1 # 获取一个字段值
"hello"
127.0.0.1:6379> HMSET myhash field1 hello1 field2 world # set多个具体 key-value
OK
127.0.0.1:6379> HMGET myhash field1 field2 # 获取多个字段值
1) "hello1"
2) "world"
127.0.0.1:6379> HGETALL myhash # 获取全部的数据
1) "field1"
2) "hello1"
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> HMSET myhash field1 hello1 field2 world
OK
127.0.0.1:6379> HGETALL myhash
1) "field2"
2) "world"
3) "field1"
4) "hello1"
127.0.0.1:6379> hlen myhash # 获取hash表的字段数量
(integer) 2

############################################################
127.0.0.1:6379> HEXISTS myhash field1 # 判断hash中指定字段是否存在
(integer) 1
127.0.0.1:6379> HEXISTS myhash field3
(integer) 0

############################################################
127.0.0.1:6379> hkeys myhash # 值获得所有field
1) "field2"
2) "field1"
127.0.0.1:6379> HVALS myhash # 只获得所有value
1) "world"
2) "hello1"

hash变更的数据user name age ,尤其是用户信息之类的,经常变动的信息

Zset(有序集合)

在set的基础上,增加了一个值,set k1 v1 zset k1 score1 v1

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
127.0.0.1:6379> zadd myset 1 one	# 添加一个值
(integer) 1
127.0.0.1:6379> ZADD myset 2 two 3 three # 添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE myset 0 -1
1) "one"
2) "two"
3) "three"
############################################################
排序如何实现
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 xiaoming
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf # 显示全部用户 从小到大
1) "xiaoming"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf 2500 withscores
1) "xiaoming"
2) "500"
3) "xiaohong"
4) "2500"
############################################################

127.0.0.1:6379> zrange salary 0 -1
1) "xiaoming"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> zrem salary xiaohong # 移除有序集合的指定数据
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "xiaoming"
2) "zhangsan"

############################################################