一、redis中对字符串类型的数据结构的操作与使用
字符串是redis的最基础的数据结构,其他的集中类型的数据结构都是在字符串的基础上构建的。字符串类型的值可以是字符串、数字、二进制,但是指最大不能超过512M。
1、字符串的基本操作
(1)设置值
命令:SET key value [EX seconds] [PX milliseconds] [NX|XX]
选项:EX seconds:为键设置妙级的过期时间, 相当于setex命令
PX milliseconds:为键设置毫秒级别的过期时间
NX:键必须不存在,才可以设置成功,用于添加,相当于setnx命令
XX:键必须存在,才可以设置,用于更新
# 设置一个键,值为dayi1234
127.0.0.1:6379> SET name dayi1234
OK
# 添加一个键hello,值为world
127.0.0.1:6379> SETNX hello world
(integer) 1
# 更新键name的值
127.0.0.1:6379> set name dayi123 xx
OK
(2)获取值
命令:GET key
# 获取设置的name的值
127.0.0.1:6379> GET name
"dayi123"
(3)批量设置值
命令:MSET key value [key value ...]
# 同时设置多个键值对
127.0.0.1:6379> MSET name liuy age 25 job it
OK
(4)批量获取值
命令:MGET key [key ...]
# 获取刚才设置的多个键的值
127.0.0.1:6379> MGET name age job
1) "liuy"
2) "25"
3) "it"
相对于获取及设置单个值,批量操作有助于提高业务效率。
(5)计数
命令:INCR key
Inrc用于对值做自增操作,返回结果中,如果值不是整数,则返回错误;值是整数,则返回自增后的结果;如果键不存在,按照值为0自增,返回结果为1。
除了inrc外,redis还有自减decr命令,自增指定数字incrby命令、自减指定数字decrby命令以及自增浮点数incrbyfloat命令。
# 对年龄自增
127.0.0.1:6379> INCR age
(integer) 26
# 由于name为字符串所以报错
127.0.0.1:6379> incr name
(error) ERR value is not an integer or out of range
# 对一个不存在的键自增,则返回1
127.0.0.1:6379> incr age1
(integer) 1
# 对年龄进行自减
127.0.0.1:6379> DECR age
(integer) 25
# 对年龄自减指定的数字
127.0.0.1:6379> DECRBY age 8
(integer) 17
(6)追加值
命令:APPEND key value
# 向字符串末尾追加字符串
127.0.0.1:6379> APPEND name an
(integer) 6
127.0.0.1:6379> get name
"liuyan"
(7)获取字符串的长度
命令:STRLEN key
# 获取name的值得长度
127.0.0.1:6379> STRLEN name
(integer) 6
(8)设置值并返回原值
命令:GETSET key value
# 设置一键值
127.0.0.1:6379> GETSET city shanghai
(nil)
127.0.0.1:6379> get city
"shanghai"
# 重新设置时会返回上一个值
127.0.0.1:6379> GETSET city beijing
"shanghai"
127.0.0.1:6379> get city
"beijing"
(9)设置指定位置的字符串
命令:SETRANGE key offset value
127.0.0.1:6379> get name
"liuyan"
127.0.0.1:6379> SETRANGE name 3 L
(integer) 6
127.0.0.1:6379> GET name
"liuLan"
(10)获取部分字符串
命令:GETRANGE key start end
# 查看第0个到第二个字符串
127.0.0.1:6379> GETRANGE name 0 2
"liu"
2、字符串的内部编码
字符串的内部编码有三种,分别是8个字节的长整型(int),小于等于39个字节的字符串(embstr),大于39个字节的字符串(raw),redis会根据当前值得类型和长度决定使用哪种内部编码实现。
# name的内部编码为raw
127.0.0.1:6379> OBJECT encoding name
"raw"
# age的内部编码为int
127.0.0.1:6379> OBJECT encoding age
"int"
3、字符串类型主要应用场景
(1)缓存
(2)计数
(3)共享session
(4)限速
二、redis中对hash类型的数据的操作与使用
Redis中哈希类型的数据结构是指键值本身又是一个键值对的结构。哈希类型中的映射关系叫做field-value,value值field对应的值。
1、hash类型数据结构的操作命令
(1)设置值
命令:HSET key field value
# 设置一个hash类型的键值
127.0.0.1:6379> HSET user:1 name dayi
(integer) 1
127.0.0.1:6379> HSET user:1 age 22
(integer) 1
(2)获取值
命令:HGET key field
# 获取user:1的name域对应的值
127.0.0.1:6379> HGET user:1 name
"dayi"
# 获取user:1下的所有值
127.0.0.1:6379> HGETALL user:1
1) "name"
2) "dayi"
3) "age"
4) "22"
(3)删除field
命令:HDEL key field [field ...]
# 删除user:1的age
127.0.0.1:6379> HDEL user:1 age
(integer) 1
(4)计算field的个数
命令:HLEN key
# 计算user:1中field的
127.0.0.1:6379> HLEN user:1
(integer) 1
(5)批量设置faield-value
命令:HMSET key field value [field value ...]
# 设置一个user:3,同时设置多个faield-value
127.0.0.1:6379> HMSET user:3 name day age 25 job it city shanghai
OK
(6)批量获取faield-value
命令:HMGET key field [field ...]
# 获取刚设置的user:3中的name、city、age的值
127.0.0.1:6379> HMGET user:3 name age city
1) "day"
2) "25"
3) "shanghai"
(7)判断field是否存在
命令:HEXISTS key field
# 判断user:3中的name是否存在
127.0.0.1:6379> HEXISTS user:3 name
(integer) 1
(8)获取所有的field
命令:HKEYS key
# 获取user:3中的所有key
127.0.0.1:6379> HKEYS user:3
1) "name"
2) "age"
3) "job"
4) "city"
(9)获取所有的value
命令:HVALS key
# 获取user:3中的所有value
127.0.0.1:6379> HVALS user:3
1) "day"
2) "25"
3) "it"
4) "shanghai"
(10)计算value的字符串长度
命令:HSTRLEN key field
# 计算user:3中city值得字符串长度
127.0.0.1:6379> HSTRLEN user:3 city
(integer) 8
2、hash类型的内部编码
(1)ziplist(压缩列表):当hash类型元素个数小于hash-max-ziplist-entries配置(默认512个),同时所有的值都小于hash-max-ziplist-value配置(默认64字节),redis会使用ziplist。Ziplist节省内存。
(2)hashtable(哈希表):hash无法满足ziplist时会使用hashtable。
# 查看user:3的内部编码
127.0.0.1:6379> OBJECT encoding user:3
"ziplist"
3、应用场景
主要用于缓存。
三、redis中对list类型的数据的操作与使用
Redis中列表是用来存储多个有序的字符串,列表中的每个字符串称之为元素,一个列表最多可以存储2^32-1个元素,redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表,获取指定索引下表元素。列表可以充当栈和队列的角色。
列表的特点:列表中的元素是有序的,可以通过索引或者下标获取某个元素或者某个范围内的原色列表;列表中的元素可以是重复的。
1、列表类型的数据操做命令
(1)添加
命令:
从右边插入元素:RPUSH key value [value ...]
从左边插入元素:LPUSH key value [value ...]
向某个元素前或者后插入元素:LINSERT key BEFORE|AFTER pivot value
# 从右边插入元素3、2、1
127.0.0.1:6379> RPUSH list1 3 2 1
(integer) 3
# 从左边插入元素4、5、6
127.0.0.1:6379> LPUSH list1 4 5 6
(integer) 6
# 在3的后面插入0
127.0.0.1:6379> LINSERT list1 AFTER 3 0
(integer) 7
(2)查找元素
命令:
获取指定范围内的元素列表:LRANGE key start stop
获取列表指定索引下表的元素:LINDEX key index
获取列表的长度:LLEN key
#获取当前列表的长度
127.0.0.1:6379> LLEN list1
(integer) 7
#查看当前列表中的所有元素
127.0.0.1:6379> LRANGE list1 0 -1
1) "6"
2) "5"
3) "4"
4) "3"
5) "0"
6) "2"
7) "1"
#获取列表的最后一个元素
127.0.0.1:6379> LINDEX list1 -1
"1"
#获取列表中的第二个元素
127.0.0.1:6379> LINDEX list1 2
"4"
(3)删除元素
命令:
从列表的左侧弹出元素:LPOP key
从列表的右侧弹出元素:RPOP key
按照索引范围修改列表:LTRIM key start stop
删除指定的元素:LREM key count value
LREM会从列表中找到等于value的元素进行删除,当count大于0时,从左到右, 删除最多count个元素,当count小于0时,从右到左,删除最多count绝对值个元素, 当count等于0时,删除所有的值为value的元素。
#从列表的最左侧删除一个元素
127.0.0.1:6379> LPOP list1
"6"
#从列表的最右侧删除一个元素
127.0.0.1:6379> RPOP list1
"1"
# 只保留第二道第六个元素,即第一个元素会被删除
127.0.0.1:6379> LTRIM list1 1 5
OK
# 从左边开始添加五个元素
127.0.0.1:6379> LPUSH list1 1 1 1 1 1
(integer) 9
# 从左边开始删除4个1
127.0.0.1:6379> LREM list1 4 1
(integer) 4
(4)修改元素
命令(根据索引下表修改):LSET key index value
# 将第0个元素的值修改为start
127.0.0.1:6379> LSET list1 0 start
OK
(5)阻塞操作
命令:阻塞式弹出命令:BLPOP key [key ...] timeout
BRPOP key [key ...] timeout
blpop和brpop是lpop和rpop的阻塞版本,在使用的过程中,如果列表为空,客户端会等到timeout时间到后会自动返回,如果timeout等于0则会一直等待下去;如果列表不为空,则会立即返回。
# 列表为空等待三秒后返回结果
127.0.0.1:6379> BRPOP list2 3
(nil)
(3.05s)
# 列表不为空,会立即返回结果
127.0.0.1:6379> BRPOP list1 3
1) "list1"
2) "2
在使用brop时,如果是多个键,那么brop会从左至右遍历键,一旦有一个键能弹出键,客户端立即返回;如果多个客户端对同一个键执行brpop,那么最先执行brpo命令的客户端可以获取弹出的值。
2、列表类型的内部编码
(1)ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512),同时列表中每个元素的值都小于list-max-ziplist-value(默认64字节)时使用ziplist。
(2)linkdedlist(链表):当列表类型五码满足ziplist时。
(3)quicklist(快速列表):Redis 3.2版本中新加的数据结构,用在列表的底层实现
#查看刚才设置的列表的内部编码
127.0.0.1:6379> OBJECT encoding list1
"quicklist"
3、列表应用场景
(1)lpush+lpop=stack(栈)
(2)lpush+rpop=queue(队列)
(3)lpush+ltrim=capped collection(有限集合)
(4)lpush+brpop=message queue(消息队列)
四、redis中对set类型的数据的操作与使用
集合类型也是用来保存多个字符串元素,并且集合中不能有重复元素,并且集合中的元素是无序的,也就意味着集合不能通过下标获取元素。一个集合最多可以存储2^32-1个元素。Redis对集合的操作除了增删改查外,还可以对多个集合取交集、并集、差集。
1、集合内的操作命令
(1)添加元素
命令:SADD key member [member ...]
# 对集合添加元素
127.0.0.1:6379> SADD set1 a b c d
(integer) 4
(2)删除元素
命令:SREM key member [member ...]
# 删除集合set中的元素a、b
127.0.0.1:6379> SREM set1 a b
(integer) 2
(3)计算元素的个数
命令:SCARD key
Scard不会遍历集合所有元素,直接用redis内部变量
# 计算集合set11元素的数量
127.0.0.1:6379> SCARD set1
(integer) 2
(4)判断元素是否在集合中
命令:SISMEMBER key member
# 判断元素c是否在集合set1中
127.0.0.1:6379> SISMEMBER set1 c
(integer) 1
(5)随机从集合返回指定个数元素
命令:SRANDMEMBER key [count]
Count为返回元素的个数,不指定个数,默认为1
# 从集合set1中随机弹出一个元素
127.0.0.1:6379> SRANDMEMBER set1
"c"
(6)获取集合中所有的元素
命令:SMEMBERS key
# 获取集合set1中的所有元素
127.0.0.1:6379> SMEMBERS set1
1) "d"
2) "c"
(7)从集合中随机弹出元素
命令: SPOP key [count]
Count为随机弹出元素的个数,不指定则默认为1
# 从集合set1中随机弹出一个元素
127.0.0.1:6379> SPOP set1
"d"
# 查看弹出后剩余的元素个数
127.0.0.1:6379> SMEMBERS set1
1) "c"
2、集合间的操作命令
集合间的操作主要有求集合的交集、并集及差集
# 在操作前先设置两个集合
127.0.0.1:6379> SADD myset1 a b c d e
(integer) 5
127.0.0.1:6379> SADD myset2 e f 0 1 2
(integer) 5
(1)求多个集合的交集
命令:SINTER key [key ...]
求到的交集保存到新的集合中命令:SINTERSTORE destination key [key ...]
# 求集合myset1和myset2的交集
127.0.0.1:6379> SINTER myset1 myset2
1) "e"
# 将求到的交集保存到新的集合mytestsinter中
127.0.0.1:6379> SINTERSTORE mytestsinter myset1 myset2
(integer) 1
(2)求多个集合的并集
命令:SUNION key [key ...]
将求到的并集保存到新的集合中命令:SUNIONSTORE destination key [key ...]
# 求集合myset1和myset2的并集
127.0.0.1:6379> SUNION myset1 myset2
1) "a"
2) "f"
3) "e"
4) "0"
5) "b"
6) "1"
7) "d"
8) "c"
9) "2
(3)求集合的差集
命令:SDIFF key [key ...]
将求到的差集保存到新的集合中的命令: SDIFFSTORE destination key [key ...]
# 求集合myset1和myset2的差集,会将myset1中有的,myset2中没有的元素打印出来
127.0.0.1:6379> SDIFF myset1 myset2
1) "a"
2) "b"
3) "d"
4) "c
3、集合的内部编码
(1)intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intest-entries配置时。
(2)hashtable(哈希表):无法满足inset时会使用hashtable
# 集合myset2中有字母,所以编码为hashtable
127.0.0.1:6379> OBJECT encoding myset2
"hashtable"
4、集合使用场景
(1)sadd = tagging(标签)
(2)spop/srandmember = random item(生成随机数,如抽奖)
(3)sadd + sinter = Social Graph(社交需求)
五、redis中对有序集合类型的数据的操作与使用
有序集合相对于集合而言,有序集合中的元素是可以排序的,有序集合排序的依据是是给每个元素设置一个分数(score)做为排序的依据。有序集合中的元素是不能重复的,但是元素的分数(score)是可以重复的。
1、有序集合内的操作命令
(1)添加成员
命令:ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
选项说明:
Nx:member必须不存在,才可以设置成功,用于添加
Xx: member必须存在,才可以设置成功,用于更新。
Ch: 返回此次操作后,有序集合元素和分数发生变化的个数。
Incr:对score做增加
# 向有序集合中添加一个元素
127.0.0.1:6379> ZADD class:1 100 dayi123
(integer) 1
# 向有序集合中添加多个元素
127.0.0.1:6379> ZADD class:1 101 liu 102 liuyi 103 dyi
(integer) 3
# 更新dayi123的分数,并返回操作后分数发生变化的元素的个数
127.0.0.1:6379> ZADD class:1 xx ch 200 dayi123
(integer) 1
(2)计算成员的个数
命令:ZCARD key
# 计算class:1的元素个数
127.0.0.1:6379> ZCARD class:1
(integer) 4
(3)计算某个成员的分数
命令:ZSCORE key member
# 计算class:1中dayi123的分数
127.0.0.1:6379> ZSCORE class:1 dayi123
"200"
(4)计算成员的排名
命令:ZRANK key member
ZREVRANK key member
ZRANK依据分数从低到高进行排名,ZREVRANK是依据分数从高到低进行排名
# 从高到低获取dayi123的名次
127.0.0.1:6379> ZREVRANK class:1 dayi123
(integer) 0
# 从低到高获取dayi123的名次
127.0.0.1:6379> ZRANK class:1 dayi123
(integer) 3
(5)删除成员
命令:ZREM key member [member ...]
# 删除class:1中的成员liu
127.0.0.1:6379> ZREM class:1 liu
(integer) 1
(6)增加成员分数
命令:ZINCRBY key increment member
# 给class:1中成员dayi123再增加50分
127.0.0.1:6379> ZINCRBY class:1 50 dayi123
"250"
(7)返回指定排名范围的成员
命令:ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
ZRANGE是依据分数从低到高返回,ZREVRANGE是依据分数从高到低返回。
# 依据分数从高到低返回class:1中的排名一二的成员
127.0.0.1:6379> ZREVRANGE class:1 0 1
1) "dayi123"
2) "dyi"
# 依据分数从低到高返回class:1中排名一二的成员
127.0.0.1:6379> ZRANGE class:1 0 1
1) "liuyi"
2) "dyi"
(8)返回指定分数范围的成员
命令: ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
ZRANGEBYSCORE按照分数从低到高返回,ZREVRANGEBYSCORE按照分数从高到低返回,
Max,min支持开区间,-inf和+inf分别代表无限小和无限大
选项:
WITHSCORES:同时返回每个成员的分数
[LIMIT offset count]:限制输出的起始位置和个数
# 输出分数100到两百之间的元素并依据分数从小到大排序
127.0.0.1:6379> ZRANGEBYSCORE class:1 100 200 withscores
1) "liuyi"
2) "102"
3) "dyi"
4) "103"
# 输出分数100到两百之间的元素并依据分数大到小排序
127.0.0.1:6379> ZREVRANGEBYSCORE class:1 200 100 withscores
1) "dyi"
2) "103"
3) "liuyi"
4) "102
# 输出分数小于200的元素,并依据分数从高到底排序
127.0.0.1:6379> ZREVRANGEBYSCORE class:1 (200 -inf withscores
1) "dyi"
2) "103"
3) "liuyi"
4) "102"
(9)返回指定分数范围成员个数
命令:ZCOUNT key min max
# 返回分数为100到两百之间的成员的个数
127.0.0.1:6379> ZCOUNT class:1 100 200
(integer) 2
(10)删除指定排名内的成员(按照升序)
命令:ZREMRANGEBYRANK key start stop
# 按照升序删除排名第一二的元素
127.0.0.1:6379> ZREMRANGEBYRANK class:1 0 1
(integer) 2
(11)删除指定分数的成员
命令:ZREMRANGEBYSCORE key min max
# 删除分数大于两百分的成员
127.0.0.1:6379> ZREMRANGEBYSCORE class:1 (200 +inf
(integer) 1
2、有序集合间的操作
# 操作前先插入先设置两个有序集合
127.0.0.1:6379> ZADD class:1 100 dayi123 99 lisi 89 wanger 96 zhangsan
(integer) 4
127.0.0.1:6379> ZADD class:2 99 dayi 95 lisi 60 zhangsan 80 liu
(integer) 4
(1)求交集
命令:ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
参数:
destination:将交集的结果保存到这个键
numkeys:需要做交集计算键的个数
key [key ...] :需要做交集的键
[WEIGHTS weight]:键的权重,默认是1,做交集是每个键的member将自己的分数乘以这个权重
[AGGREGATE SUM|MIN|MAX]:做交集后的汇总方式,默认是sum
# 求class:1和class:2的交集
127.0.0.1:6379> ZINTERSTORE class 2 class:1 class:2
(integer) 2
127.0.0.1:6379> ZRANGE class 0 -1 withscores
1) "zhangsan"
2) "156"
3) "lisi"
4) "194"
(2)并集
命令:ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
参数:同求交集命令参数相同
# 求class:1和class:2的并集,会对相同元素的分数相加
127.0.0.1:6379> ZUNIONSTORE class:union 2 class:1 class:2
(integer) 6
127.0.0.1:6379> ZRANGE class:union 0 -1 withscores
1) "liu"
2) "80"
3) "wanger"
4) "89"
5) "dayi"
6) "99"
7) "dayi123"
8) "100"
9) "zhangsan"
10) "156"
11) "lisi"
12) "194"
3、有序集合的内部编码
(1)ziplist(压缩列表):有序元素的个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,redis会用ziplist,ziplist能有效减少内存的使用。
(2)skiplist(跳跃表):ziplist条件不满足时使用。
# class:union满足ziplist条件,所以内部编码是ziplist
127.0.0.1:6379> OBJECT encoding class:union
"ziplist"
4、有序集合的使用场景
排行榜系统