1 引言
redis的重要性不必多说,几乎在任何项目中都可以看到redis的身影,本文不介绍redis的安装与配置,着重说redis应用,我使用的环境是阿里云服务器加上docker,在docker hub上拉取到redis镜像,然后创造一个容器,运行在docker上面。
2 redis常用数据类型
2.1 常用key操作
显示所有key
keys * (* 表示通配符)
127.0.0.1:6379[1]> keys *
(empty array)
设置key
set key value
127.0.0.1:6379[1]> set k1 kobe
OK
127.0.0.1:6379[1]> set k2 wade
OK
127.0.0.1:6379[1]> set k3 paul
OK
127.0.0.1:6379[1]> keys *
1) "k3"
2) "k1"
3) "k2"
检查key的类型
type key
127.0.0.1:6379[1]> type key1
none
127.0.0.1:6379[1]> type k1
string
判断key是否存在
exists key
127.0.0.1:6379[1]> exists k1
(integer) 1
127.0.0.1:6379[1]> exists k4
(integer) 0
设置key的过期时间
expire key seconds ttl key -1 表示永不过期,-2 表示已经过期,正整数表示还剩几秒过期
127.0.0.1:6379[1]> expire k1 10
(integer) 1
127.0.0.1:6379[1]> ttl k1
(integer) 7
127.0.0.1:6379[1]> ttl k1
(integer) 2
127.0.0.1:6379[1]> ttl k1
(integer) 0
127.0.0.1:6379[1]> ttl k1
(integer) -2
删除元素
del key : 同步删除 unlink key :异步删除
127.0.0.1:6379[1]> del k2
(integer) 1
127.0.0.1:6379[1]> unlink k3
(integer) 1
切换数据库
redis 默认有16个DB,索引是0~15,默认是0
select index
127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> select 1
OK
127.0.0.1:6379[1]> select 0
OK
查看db中key的个数
dbsize
127.0.0.1:6379[1]> dbsize
(integer) 1
清空当前库
flushdb
清空所有库
flushall
2.2 String
string是最基本的数据类型,一个key对应一个value,String类型二进制安全,value可以是任何数据,比如图片或者序列化对象,最大不能超过512MB.
添加键值对
127.0.0.1:6379[1]> set k1 v1
OK
设置超时时间键值对
setex key seconds value
127.0.0.1:6379[1]> setex k2 10 v2
OK
127.0.0.1:6379[1]> ttl k2
(integer) 6
127.0.0.1:6379[1]> ttl k2
(integer) 4
127.0.0.1:6379[1]> ttl k2
(integer) 0
127.0.0.1:6379[1]> ttl k2
(integer) -2
设置库中没有的key
setnx key value 这里面的key必须是新key
127.0.0.1:6379[1]> keys *
1) "k1"
127.0.0.1:6379[1]> get k1
"v1"
127.0.0.1:6379[1]> setnx k1 v100
(integer) 0
127.0.0.1:6379[1]> get k1
"v1"
127.0.0.1:6379[1]> setnx k2 v2
(integer) 1
127.0.0.1:6379[1]> get k2
"v2"
在key对应的值尾部添加一些字符
append key value
127.0.0.1:6379[1]> get k1
"v1"
127.0.0.1:6379[1]> append k1 haha
(integer) 6
127.0.0.1:6379[1]> get k1
"v1haha"
获取key对应的值长度
strlen key
127.0.0.1:6379[1]> strlen k1
(integer) 6
数值型值递增,递减
redis的递增和递减是原子性操作
incr key decr key incrby key increment decrby key decrement
127.0.0.1:6379[1]> get k3
"1"
127.0.0.1:6379[1]> incr k3
(integer) 2
127.0.0.1:6379[1]> incr k3
(integer) 3
127.0.0.1:6379[1]> decr k3
(integer) 2
127.0.0.1:6379[1]> decr k3
(integer) 1
127.0.0.1:6379[1]> incrby k4 10
(integer) 10
127.0.0.1:6379[1]> incrby k4 10
(integer) 20
127.0.0.1:6379[1]> incrby k4 10
(integer) 30
127.0.0.1:6379[1]> incrby k4 10
(integer) 40
127.0.0.1:6379[1]> decrby k4 20
(integer) 20
127.0.0.1:6379[1]> decrby k4 20
(integer) 0
同时设置一个或多个
mset key value [key value…]
127.0.0.1:6379[1]> mset k1 v1 k2 v2
OK
127.0.0.1:6379[1]> keys *
1) "k1"
2) "k2"
同时读取多个
mget key [key…]
127.0.0.1:6379[1]> mget k1 k2
1) "v1"
2) "v2"
同时设置一个或多个不存在的key
msetnx key value [key value…]
127.0.0.1:6379[1]> msetnx k1 v1 k2 v2
(integer) 1
127.0.0.1:6379[1]> keys *
1) "k1"
2) "k2"
获取指定范围的值 getrange key start end
127.0.0.1:6379[1]> set k3 "hello world"
OK
127.0.0.1:6379[1]> get k3
"hello world"
127.0.0.1:6379[1]> getrange k3 0 5
"hello "
以新值换旧值
getset key value
127.0.0.1:6379[1]> get k3
"hello world"
127.0.0.1:6379[1]> getset k3 haha
"hello world"
127.0.0.1:6379[1]> get k3
"haha"
String的数据结构
String的数据结构为简单动态字符串(Simple Dynamic String SDS)。是可以修改的字符串,内部结构实现类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。 内部为当前字符串实际分配的空间一般要高于实际字符串长度len,当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时只会多扩1M的空间,需要注意的是字符串最大长度为512M。
2.3 List
简介
单键多值
Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素列表的头部(左边)或者尾部(右边)它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会比较差
从List左侧插入值
lpush key element [element…]
127.0.0.1:6379[1]> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
通过输出结果可以看出lpush指令是链表的头插法。
从List右侧插入值
127.0.0.1:6379[1]> rpush k2 v1 v2 v3
(integer) 3
127.0.0.1:6379[1]> lrange k2 0 -1
1) "v1"
2) "v2"
3) "v3"
通过输出结果可以看出rpush指令是链表的尾插法。
从列表的左边或右边取值
lpop/rpop key [count] 值在健在,值没有健就没有了
127.0.0.1:6379[1]> lpop k1
"v3"
127.0.0.1:6379[1]> rpop k1
"v1"
127.0.0.1:6379[1]> rpop k1
"v2"
127.0.0.1:6379[1]> rpop k1
(nil)
从一个键的右侧取值,插到另一个键的左侧
rpoplpush source destination
127.0.0.1:6379[1]> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379[1]> lpush k2 v11 v12 v13
(integer) 3
127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379[1]> lrange k2 0 -1
1) "v13"
2) "v12"
3) "v11"
127.0.0.1:6379[1]> rpoplpush k1 k2
"v1"
127.0.0.1:6379[1]> lrange k2 0 -1
1) "v1"
2) "v13"
3) "v12"
4) "v11"
获取指定索引的数据 lindex key index
127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "v2"
127.0.0.1:6379[1]> lindex k1 0
"v3"
获取列表的长度
llen key
127.0.0.1:6379[1]> llen k1
(integer) 2
在列表某个元素的前或后插入一个新元素 linsert key before|after pivot element
127.0.0.1:6379[1]> linsert k1 after "v3" "hello"
(integer) 3
127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "hello"
3) "v2"
127.0.0.1:6379[1]> linsert k1 before "v3" "world"
(integer) 4
127.0.0.1:6379[1]> lrange k1 0 -1
1) "world"
2) "v3"
3) "hello"
4) "v2"
移除某个元素,可以指定移除的个数 lrem key count element
127.0.0.1:6379[1]> lrem k1 2 "v2"
(integer) 1
127.0.0.1:6379[1]> lrange k1 0 -1
1) "world"
2) "v3"
3) "hello"
修改指定索引位置的值
lset key index element
127.0.0.1:6379[1]> lset k1 1 "ni"
OK
127.0.0.1:6379[1]> lrange k1 0 -1
1) "world"
2) "ni"
3) "hello"
数据结构
List的数据结构为quickList 数据很少时,会分配一块连续的内存空间,形成一个zipList(压缩列表) 数据很多时,会分配多个zipList ,多个zipList使用链表链接
2.4 Set
简介
Set与List类似是一个列表的功能,特殊之处是set内的元素不可以重复,用于存储和维护一个没有重复数据的列表数据。 Set是String类型的无序集合,底层是一个value为null的hash表,添加、删除、查找都是O(1)
往集合中添加元素
sadd key member [member …]
127.0.0.1:6379[1]> sadd k1 v1 v2 v3
(integer) 3
查看集合中的元素
smembers key
127.0.0.1:6379[1]> smembers k1
1) "v3"
2) "v2"
3) "v1"
判断某个元素是否在集合中
sismember key member
127.0.0.1:6379[1]> sismember k1 "v1"
(integer) 1
127.0.0.1:6379[1]> sismember k1 v2
(integer) 1
127.0.0.1:6379[1]> sismember k1 v4
(integer) 0
获取集合中元素的个数
scard key
127.0.0.1:6379[1]> scard k1
(integer) 3
删除集合中某个元素或多个元素
srem key member [member…]
127.0.0.1:6379[1]> srem k1 v1
(integer) 1
127.0.0.1:6379[1]> smembers k1
1) "v3"
2) "v2"
随机删除一个或多个元素并返回
spop key [count] 值没有了,健就消失了
127.0.0.1:6379[1]> spop k1
"v2"
127.0.0.1:6379[1]> spop k1
"v3"
127.0.0.1:6379[1]> spop k1
(nil)
随机获取几个元素,不删除
127.0.0.1:6379[1]> sadd k2 v1 v2 v3 v4
(integer) 4
127.0.0.1:6379[1]> srandmember k2 2
1) "v1"
2) "v4"
127.0.0.1:6379[1]> srandmember k2 2
1) "v1"
2) "v2"
127.0.0.1:6379[1]> smembers k2
1) "v3"
2) "v4"
3) "v2"
4) "v1"
将一个集合的某个元素移动到另一个集合中
smove source destination member
127.0.0.1:6379[1]> sadd k1 v100 v200
(integer) 2
127.0.0.1:6379[1]> keys *
1) "k1"
2) "k2"
127.0.0.1:6379[1]> smove k1 k2 v100
(integer) 1
127.0.0.1:6379[1]> smembers k1
1) "v200"
127.0.0.1:6379[1]> smembers k2
1) "v3"
2) "v4"
3) "v2"
4) "v1"
5) "v100"
获取两个集合的交集
sinter key [key…]
127.0.0.1:6379[1]> sadd k3 v1 v2 v3 v4 v5
(integer) 5
127.0.0.1:6379[1]> sadd k4 v3 v4 v5 v6 v7
(integer) 5
127.0.0.1:6379[1]> sinter k3 k4
1) "v3"
2) "v4"
3) "v5"
获取两个集合的并集
sunion key [key …]
127.0.0.1:6379[1]> sunion k3 k4
1) "v7"
2) "v4"
3) "v5"
4) "v6"
5) "v3"
6) "v2"
7) "v1"
获取两个集合的差集
sdiff key [key …]
127.0.0.1:6379[1]> sdiff k3 k4
1) "v1"
2) "v2"
127.0.0.1:6379[1]> sdiff k4 k3
1) "v7"
2) "v6"
数据结构
Set数据结构是dict字典,字典是用哈希表实现的。 Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一对象,Redis的set结构也是一样,内部也使用hash结构,所有的value都指向同一个内部值。
2.5 Hash
简介 Hash是一个键值对集合,是一个string类型的field和value映射表,hash特别适合存储对象。
添加一个hash数据
hset key field value
127.0.0.1:6379[1]> hset user:1001 id 1 name zhangsan
(integer) 2
给一个hash数据添加多个field
hmset key field value [field value …]
127.0.0.1:6379[1]> hmset user:1002 id 2 name lisi age 10
OK
获取某个key的某个field
hget key field
127.0.0.1:6379[1]> hget user:1001 id
"1"
127.0.0.1:6379[1]> hget user:1001 name
"zhangsan"
获取某个key的多个field
hmget key field [field…]
127.0.0.1:6379[1]> hmget user:1002 id name age
1) "2"
2) "lisi"
3) "10"
判断某个key中是否存在某个field
hexists key field
127.0.0.1:6379[1]> hexists user:1002 id
(integer) 1
127.0.0.1:6379[1]> hexists user:1002 tt
(integer) 0
获取某个key中所有的field字段
hkeys key
127.0.0.1:6379[1]> hkeys user:1001
1) "id"
2) "name"
127.0.0.1:6379[1]> hkeys user:1002
1) "id"
2) "name"
3) "age"
获取某个key中所有field对应的value
hvals key
127.0.0.1:6379[1]> hvals user:1001
1) "1"
2) "zhangsan"
127.0.0.1:6379[1]> hvals user:1002
1) "2"
2) "lisi"
3) "10"
对某个key中的数值型field字段递增
hincrby key field increment
127.0.0.1:6379[1]> hincrby user:1002 age 2
(integer) 12
对某个key新增一对field-value对
hsetnx key field value field必须是不存在的,如果已经存在,设置不成功
127.0.0.1:6379[1]> hsetnx user:1002 age 40
(integer) 0
127.0.0.1:6379[1]> hsetnx user:1002 sex 1
(integer) 1
数据结构
当field-value 长度较短且个数较少时,使用ziplist 较多时时候hashtable
2.6 Zset(有序集合)
简介 Zset与set一样,是没有重复元素的字符串集合,有序集合的每个成员都关联一个评分,评分被用来排序,成员唯一,评分可以不唯一
添加有序集合元素
zadd key score member [score member…]
127.0.0.1:6379[1]> zadd topn 200 java 300 c++ 400 mysql 500 python
(integer) 4
获取指定范围的集合元素
zrange key min max [withscores]
127.0.0.1:6379[1]> zrange topn 0 -1
1) "java"
2) "c++"
3) "mysql"
4) "python"
127.0.0.1:6379[1]> zrange topn 0 -1 withscores
1) "java"
2) "200"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "python"
8) "500"
按照score获取指定范围的值
zrangebyscore key min max [withscores]
127.0.0.1:6379[1]> zrangebyscore topn 300 500
1) "c++"
2) "mysql"
3) "python"
127.0.0.1:6379[1]> zrangebyscore topn 300 500 withscores
1) "c++"
2) "300"
3) "mysql"
4) "400"
5) "python"
6) "500"
降序获取指定分数范围内的值
zrevrangebyscore key max min [withscores]
127.0.0.1:6379[1]> zrevrangebyscore topn 500 300 withscores
1) "python"
2) "500"
3) "mysql"
4) "400"
5) "c++"
6) "300"
递增某个成员的分数
zincrby key increment member
127.0.0.1:6379[1]> zincrby topn 50 java
"250"
获取指定分数范围内成员的个数
zcount key min max
127.0.0.1:6379[1]> zcount topn 200 300
(integer) 2
获取某个成员的排名
zrank key member 第一位返回的是0
127.0.0.1:6379[1]> zrank topn java
(integer) 0
127.0.0.1:6379[1]> zrank topn python
(integer) 3
数据结构
hash: field是成员 value是评分 跳跃表:给元素value排序,根据score的范围获取元素列表
|