数据库引擎网址https://db-engines.com/en/,有不同类型的数据库对比,架构师有个很重要的能力就是技术选型和技术对比。
Redis英文网址:https://redis.io/
Redis中文网址:http://redis.cn/
Redis的数据模型以Key、value的形式存储的。支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)、 bitmaps。支持的类型指的是value。
对比Memcache
Memcache也是key、value的形式存放数据,最重要的不同是Memcache的value没有类型,而Redis有类型。这就导致Memcache传输数据的带宽和IO销毁非常大,怎么理解这句话?比如Memcache和Redis中存储的是如下JSON数据
{
"hobby":["打篮球","踢足球","羽毛球"]
}
我们需要拿出hobby里面的第一个元素”打篮球”返回给调用者(客户端)
这种思想就是:计算向数据移动。
使用
Redis像MYSQL一样是有库的概念的,默认从0开始编号到16。库与库之间是隔离的互相看不到对方的数据。
String相关操作
面向字符串的操作
127.0.0.1:6379> set keyxx:1 hahaha //在1号库里面存放数据key为keyxx value为:hahaha
OK
127.0.0.1:6379> get keyxx //默认从0号库获取数据,库与库之间是隔离的所以获取不到
(nil)
127.0.0.1:6379> get keyxx:1 //从1号库里面获取数据
"hahaha"
切换9号库
127.0.0.1:6379> select 9
OK
127.0.0.1:6379[9]>
nx(not exisit)表示不存在k1的时候才会设置(相当于新建)
127.0.0.1:6379[9]> set k1 v1 nx
OK
127.0.0.1:6379[9]> get k1
"v1"
xx表示只有存在的时候才会设置(相当于更新)
127.0.0.1:6379> set k2 v2 xx
(nil)
127.0.0.1:6379> get k2
(nil)
mset、mget
127.0.0.1:6379> mset k3 v3 k4 v4
OK
127.0.0.1:6379> get k3
"v3"
127.0.0.1:6379> get k4
"v4"
127.0.0.1:6379> mget k3 k4
1) "v3"
2) "v4"
append
127.0.0.1:6379> get k3
"v3"
127.0.0.1:6379> append k3 haha
(integer) 6
127.0.0.1:6379> get k3
"v3haha"
getrange、setrange
127.0.0.1:6379> get k3
"v3haha"
127.0.0.1:6379>
127.0.0.1:6379> getrange k3 2 6
"haha"
127.0.0.1:6379> getrange k3 2 5
"haha"
正向索引和反向索引,以字符串abcdef为例
127.0.0.1:6379> get k3
"v3haha"
127.0.0.1:6379> getrange k3 -6 -5
"v3"
127.0.0.1:6379> getrange k3 0 1
"v3"
127.0.0.1:6379> getrange k3 0 -5
"v3"
127.0.0.1:6379> setrange k3 2 xxx
(integer) 6
127.0.0.1:6379> get k3
"v3xxxa"
strlen
127.0.0.1:6379> get k3
"v3xxxa"
127.0.0.1:6379> strlen k3
(integer) 6
type命令查看key对应的value类型
127.0.0.1:6379> help set
SET key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL] [NX|XX] [GET]
summary: Set the string value of a key
since: 1.0.0
group: string
set命令属于String组里面,那边通过set设置key的value的时候,应该也是string类型
127.0.0.1:6379> get k1
"100"
127.0.0.1:6379> type k1
string
127.0.0.1:6379> object encoding k1
"int"
面向数值的操作
可以对int这种编码类型的数据进行计算操作,比如incr、incrby、decr、decrby、incrbyfloat
127.0.0.1:6379> incr k1
(integer) 101
127.0.0.1:6379> incrby k1 3
(integer) 104
127.0.0.1:6379> decr k1
(integer) 103
127.0.0.1:6379> decrby k1 3
(integer) 100
127.0.0.1:6379> incrbyfloat k1 0.5
"100.5"
面向bitmap的操作
setbit
127.0.0.1:6379> help setbit
SETBIT key offset value
summary: Sets or clears the bit at offset in the string value stored at key
since: 2.2.0
group: string
一个字节有8个二进制位,字节有索引的概念、二进制位也有索引的概念。
setbit命令里面的offset指的是二进制位的索引,二进制位的值只能是0或者1。所以setbit设置的value也只能是0或者1
127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> strlen k1
(integer) 1
127.0.0.1:6379> get k1
"@"
Redis存储的数据都是按照字节流存储的,上面的含义是把偏移量的第1位设置成1。二进制表示就是
0 1 0 0 0 0 0 0
继续操作
127.0.0.1:6379> setbit k1 7 1
(integer) 0
127.0.0.1:6379> strlen k1
(integer) 1
127.0.0.1:6379> get k1
"A"
相当于又在第7位设置成1。对应的二进制数据为
0 1 0 0 0 0 0 1
继续操作
127.0.0.1:6379> setbit k1 9 1
(integer) 0
127.0.0.1:6379> strlen k1
(integer) 2
127.0.0.1:6379> get k1
"A@"
相当于在索引9位置设置成1,9个bit位已经超过一个字节,所以需要两个字节存储。对应的二进制位为
0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0
bitpos
127.0.0.1:6379> help bitpos
BITPOS key bit [start] [end]
summary: Find first bit set or clear in a string
since: 2.8.7
group: string
查找一个bit ,bit只能是0或者1,start和end表示的是字节的索引不是二进制的索引。返回要找bit的第一个位置。
127.0.0.1:6379> bitpos k1 1 0 1
(integer) 1
k1的二进制位为:0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0
从第0个字节到第1个字节查找bit 为1的位置。
127.0.0.1:6379> bitpos k1 1 1 1
(integer) 9
k1的二进制位为:0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0
从第1个字节到第1个字节查找bit 为1的位置。注意这次返回的是整个k1对应的二进制位1的位置
bitcount
127.0.0.1:6379> help bitcount
BITCOUNT key [start end]
summary: Count set bits in a string
since: 2.6.0
group: string
表示返回1这个bit的个数,[start end]指的是字节的索引而不是二进制位的索引
127.0.0.1:6379> bitcount k1 0 1
(integer) 3
127.0.0.1:6379> bitcount k1 0 0
(integer) 2
127.0.0.1:6379> bitcount k1 1 1
(integer) 1
bitop
127.0.0.1:6379> help bitop
BITOP operation destkey key [key ...]
summary: Perform bitwise operations between strings
since: 2.6.0
group: string
按位逻辑操作比如& | 运算。operation表示逻辑符,destkey表示逻辑运算结果存放的地方。
127.0.0.1:6379> setbit k2 1 1
(integer) 0
127.0.0.1:6379> get k2
"@"
127.0.0.1:6379> setbit k3 1 1
(integer) 0
127.0.0.1:6379> get k3
"@"
127.0.0.1:6379> bitop and andkey k2 k3
(integer) 1
127.0.0.1:6379> get andkey
"@"
List
lpush
127.0.0.1:6379> help lpush
LPUSH key element [element ...]
summary: Prepend one or multiple elements to a list
since: 1.0.0
group: list
从链表的左边开始添加元素到List中
rpush
127.0.0.1:6379> help rpush
RPUSH key element [element ...]
summary: Append one or multiple elements to a list
since: 1.0.0
group: list
从链表的右侧添加元素
lpop
127.0.0.1:6379> help lpop
LPOP key [count]
summary: Remove and get the first elements in a list
since: 1.0.0
group: list
从链表的左侧移除一个元素,并把移除的元素返回。
rpop
127.0.0.1:6379> help rpop
RPOP key [count]
summary: Remove and get the last elements in a list
since: 1.0.0
group: list
实现栈操作
127.0.0.1:6379> lpush k5 a b c d e f
127.0.0.1:6379> lpop k5
"f"
127.0.0.1:6379> lpop k5
"e"
127.0.0.1:6379> lpop k5
"d"
127.0.0.1:6379> lpop k5
"c"
127.0.0.1:6379> lpop k5
"b"
127.0.0.1:6379> lpop k5
"a"
127.0.0.1:6379> lpop k5
(nil)
127.0.0.1:6379> rpush k6 a b c d e f
127.0.0.1:6379> rpop k6
"f"
127.0.0.1:6379> rpop k6
"e"
127.0.0.1:6379> rpop k6
"d"
127.0.0.1:6379> rpop k6
"c"
127.0.0.1:6379> rpop k6
"b"
127.0.0.1:6379> rpop k6
"a"
127.0.0.1:6379> rpop k6
(nil)
使用lpush、lpop 和rpush、rpop这种同方向的命令能够实现栈的操作。
实现队列的操作
127.0.0.1:6379> lpush k5 a b c d e f
(integer) 6
127.0.0.1:6379> rpop k5
"a"
127.0.0.1:6379> rpop k5
"b"
127.0.0.1:6379> rpop k5
"c"
127.0.0.1:6379> rpop k5
"d"
127.0.0.1:6379> rpop k5
"e"
127.0.0.1:6379> rpop k5
"f"
127.0.0.1:6379> rpop k5
(nil)
127.0.0.1:6379> rpush k6 a b c d e f
(integer) 6
127.0.0.1:6379> lpop k6
"a"
127.0.0.1:6379> lpop k6
"b"
127.0.0.1:6379> lpop k6
"c"
127.0.0.1:6379> lpop k6
"d"
127.0.0.1:6379> lpop k6
"e"
127.0.0.1:6379> lpop k6
"f"
127.0.0.1:6379> lpop k6
(nil)
使用lpush、rpop 和rpush、lpop这种反方向的命令能够实现队列的操作。
lrange获取列表元素
127.0.0.1:6379> help lrange
LRANGE key start stop
summary: Get a range of elements from a list
since: 1.0.0
group: list
和字符串一样,链表List也为每个节点维护索引值。
127.0.0.1:6379> rpush k6 a b c d e f
127.0.0.1:6379> lrange k6 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
lindex 取出列表里面的一个元素
127.0.0.1:6379> lindex k6 -1
"f"
127.0.0.1:6379> lindex k6 0
"a"
lset 设置一个元素
127.0.0.1:6379> help lset
LSET key index element
summary: Set the value of an element in a list by its index
since: 1.0.0
group: list
127.0.0.1:6379> lset k6 0 xxx
OK
127.0.0.1:6379> lrange k6 0 -1
1) "xxx"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
lrem
127.0.0.1:6379> help lrem
LREM key count element
summary: Remove elements from a list
since: 1.0.0
group: list
127.0.0.1:6379> lpush k7 1 2 3 1 2 1
(integer) 6
127.0.0.1:6379> lrange k7 0 -1
1) "1"
2) "2"
3) "1"
4) "3"
5) "2"
6) "1"
127.0.0.1:6379> lrem k7 2 1
(integer) 2
127.0.0.1:6379> lrange k7 0 -1
1) "2"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379>
127.0.0.1:6379> help linsert
LINSERT key BEFORE|AFTER pivot element
summary: Insert an element before or after another element in a list
since: 2.2.0
group: list
blpop
127.0.0.1:6379> help blpop
BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0
group: list
如果超时时间设置为0,没有拿到key里面的数据会一直阻塞,直到拿到数据为值。而且先阻塞的客户端先拿到数据。比如3个客户端同时执行上面的命令,当有数据的时候,先阻塞的客户端先拿到数据
ltrim
127.0.0.1:6379> help ltrim
LTRIM key start stop
summary: Trim a list to the specified range
since: 1.0.0
group: list
删除给定范围外两端的元素
127.0.0.1:6379> lrange k7 0 -1
1) "2"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> ltrim k7 1 -2
OK
127.0.0.1:6379> lrange k7 0 -1
1) "3"
2) "2"
127.0.0.1:6379>
hash
类似hashmap
127.0.0.1:6379> help hset
HSET key field value [field value ...]
summary: Set the string value of a hash field
since: 2.0.0
group: hash
127.0.0.1:6379> help hmset
HMSET key field value [field value ...]
summary: Set multiple hash fields to multiple values
since: 2.0.0
group: hash
127.0.0.1:6379> hset person name lff
(integer) 1
127.0.0.1:6379> hmset person age 18 weight 155
OK
127.0.0.1:6379> hget person name
"lff"
127.0.0.1:6379> hmget person age weight
1) "18"
2) "155"
127.0.0.1:6379> hkeys person
1) "name"
2) "age"
3) "weight"
127.0.0.1:6379> hvals person
1) "lff"
2) "18"
3) "155"
127.0.0.1:6379> hgetall person
1) "name"
2) "lff"
3) "age"
4) "18"
5) "weight"
6) "155"
127.0.0.1:6379> hincrbyfloat person age 0.5
"18.5"
127.0.0.1:6379> hget person age
"18.5"
127.0.0.1:6379> hincrbyfloat person age -1
"17.5"
127.0.0.1:6379> hget person age
"17.5"
set
特点:无序、去重。
127.0.0.1:6379> help sadd
SADD key member [member ...]
summary: Add one or more members to a set
since: 1.0.0
group: set
127.0.0.1:6379> sadd set_test a b c a b c
(integer) 3
127.0.0.1:6379> smembers set_test
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> srem set_test a
(integer) 1
127.0.0.1:6379> smembers set_test
1) "c"
2) "b"
sinter 、sinterstore交集
127.0.0.1:6379> help sinter
SINTER key [key ...]
summary: Intersect multiple sets
since: 1.0.0
group: set
127.0.0.1:6379> help sinterstore
SINTERSTORE destination key [key ...]
summary: Intersect multiple sets and store the resulting set in a key
since: 1.0.0
group: set
sinter取交集,结果直接返回客户端,会走网卡。sinterstore取交集,结果存在一个新的key里面,不走网卡。
127.0.0.1:6379> sadd kset1 a b c d
(integer) 4
127.0.0.1:6379> sadd kset2 a b d f
(integer) 4
127.0.0.1:6379> smembers kset1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> smembers kset2
1) "d"
2) "b"
3) "a"
4) "f"
127.0.0.1:6379> sinter kset1 kset2
1) "d"
2) "b"
3) "a"
127.0.0.1:6379> sinterstore kset3 kset1 kset2
(integer) 3
127.0.0.1:6379> smembers kset3
1) "d"
2) "a"
3) "b"
sunion、sunionstore并集
127.0.0.1:6379> help sunion
SUNION key [key ...]
summary: Add multiple sets
since: 1.0.0
group: set
sunion取并集直接返回,sunionstore取并集,结果存放一个新的key里面
127.0.0.1:6379> sunion kset1 kset2
1) "d"
2) "c"
3) "b"
4) "a"
5) "f"
127.0.0.1:6379> sunionstore kset4 kset1 kset2
(integer) 5
127.0.0.1:6379> smembers kset4
1) "d"
2) "c"
3) "b"
4) "a"
5) "f"
sorted set
给出一系列元素进行排序,应该按照什么方式排序?
比如:苹果、香蕉、橙子 是按照名称排序、还是按照大小排序、还是按照含糖量排序。所以sorted set里面引入一个分值的概念用来对元素进行排序。
有序set
127.0.0.1:6379> help zadd
ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]
summary: Add one or more members to a sorted set, or update its score if it already exists
since: 1.2.0
group: sorted_set
127.0.0.1:6379> zadd zk1 3 apple 7 bannana 1 orange
(integer) 3
127.0.0.1:6379> zrange zk1 0 -1
1) "orange"
2) "apple"
3) "bannana"
127.0.0.1:6379> zrange zk1 0 -1 withscores
1) "orange"
2) "1"
3) "apple"
4) "3"
5) "bannana"
6) "7"
按照分值范围取数据
127.0.0.1:6379> zrangebyscore zk1 3 7
1) "apple"
2) "bannana"
zrevrange逆序取数据
取出前两个最大的元素
127.0.0.1:6379> zrange zk1 0 -1 withscores
1) "orange"
2) "1"
3) "apple"
4) "3"
5) "bannana"
6) "7"
127.0.0.1:6379> zrevrange zk1 0 1
1) "bannana"
2) "apple"
获取分值和排名
127.0.0.1:6379> help zscore
ZSCORE key member
summary: Get the score associated with the given member in a sorted set
since: 1.2.0
group: sorted_set
127.0.0.1:6379> help zrank
ZRANK key member
summary: Determine the index of a member in a sorted set
since: 2.0.0
group: sorted_set
127.0.0.1:6379> zscore zk1 apple
"3"
127.0.0.1:6379> zrank zk1 apple
(integer) 1
zincrby
给sorted set 集合某一个元素的分值增加,增加后也实时维护其在集合里面的顺序
127.0.0.1:6379> help zincrby
ZINCRBY key increment member
summary: Increment the score of a member in a sorted set
since: 1.2.0
group: sorted_set
127.0.0.1:6379> zrange zk1 0 -1 withscores
1) "orange"
2) "1"
3) "apple"
4) "3"
5) "bannana"
6) "7"
127.0.0.1:6379> zincrby zk1 3 orange
"4"
127.0.0.1:6379> zrange zk1 0 -1 withscores
1) "apple"
2) "3"
3) "orange"
4) "4"
5) "bannana"
6) "7"
zunionstore
127.0.0.1:6379> help zunionstore
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
summary: Add multiple sorted sets and store the resulting sorted set in a new key
since: 2.0.0
group: sorted_set
默认是sum排序,相同集合里面的元素求和
127.0.0.1:6379> zadd k1 60 jack 80 rose 100 yoga
(integer) 3
127.0.0.1:6379> zadd k2 40 jack 20 rose 60 cliff
(integer) 3
127.0.0.1:6379> zunionstore k3 2 k1 k2 //2为key的个数,这里key有两个k1、k2
(integer) 4
127.0.0.1:6379> zrange k3 0 -1 withscores
1) "cliff"
2) "60"
3) "jack"
4) "100"
5) "rose"
6) "100"
7) "yoga"
8) "100"
可以给权重进行排序,k2给的权重是0.5,合并的时候k2集合里面的分值都会0.5倍
127.0.0.1:6379> zunionstore k3 2 k1 k2 weights 1 0.5
(integer) 4
127.0.0.1:6379> zrange k3 0 -1 withscores
1) "cliff"
2) "30"
3) "jack"
4) "80"
5) "rose"
6) "90"
7) "yoga"
8) "100"