目录


  • Redis的基本类型
  • 字符串
  • 哈希
  • 列表
  • 集合
  • 有序集合
  • 其他




Redis的基本类型

本文使用的Redis版本为: Redis 3.0.503 (00000000/0) 64 bit / windows 环境 下载链接 l点击这里下载

概述

Redis有五种数据结构:字符串、哈希、列表、集合、有序集合
Redis可以用来干嘛:缓存、排行榜系统(热度排行)、计数器应用(视频播放量)、社交网络(点赞和踩)、消息队列

Redis不可以用来干嘛:Redis不适合数据量较大的储存

Redis为什么这么快:

1 纯内存访问,Redis将所有数据都放在内存中,内存响应时间快

2 非阻塞I/O,Redis使用epoll作为I/O多路复用技术,Redis自身的时间处理模型将epoll中的连接读写关闭都转换为时间,不在网络I/O上浪费过多的时间

3 单线程避免了线程切换和竞态产生的消耗 (如果某个命令执行时间过长会造成其他命令的阻塞)

Redis通用的命令:

命令

命令作用

返回值

keys *

查看所有的建

键 的所有集合/empty

dbsize

查看键的数量

键的数量/empty

exists key

查看键是否存在

1/0

del key [key...]

删除键,可以删除多个

返回删除键的数量/0

expire key seconds

设置键的过期时间,到期自动删除

1/0

ttl key

查看键的剩余过期时间

剩余时间/-2(表示已被删除)/-1(表示没有设置过期时间)

type key

查看键的数据结构类型

五种类型/none

字符串

字符串是redis最基础的数据结构

字符串的实际值可以是:字符串(简单的字符串,复杂的字符串(xml json)),数字(整数,浮点数),二进制(图片,音频) 但是最大值不能超过512MB

字符串的基本命令
  1. 常用命令:
  1. 设置值 set key value [ex +x秒] [px+x毫秒] [nx|xx]
    ex 后面+设置过期的秒数 px 后面+过期的毫秒数
    nx 键值必须不存在才可以设置成功,用于添加
    xx 键值必须存在才可以设置成功,用于更新
127.0.0.1:6379[1]> set a 1 ex 10000 nx
OK
127.0.0.1:6379[1]> ttl a
(integer) 9997
127.0.0.1:6379[1]> set a 2 nx
(nil)
127.0.0.1:6379[1]> set a 2 xx
OK
127.0.0.1:6379[1]> keys *
1) "a"
127.0.0.1:6379[1]> ttl a
(integer) -1
127.0.0.1:6379[1]> set a 1 ex 10000 nx
OK
127.0.0.1:6379[1]> ttl a
(integer) 9997
127.0.0.1:6379[1]> set a 2 nx
(nil)
127.0.0.1:6379[1]> set a 2 xx
OK
127.0.0.1:6379[1]> keys *
1) "a"
127.0.0.1:6379[1]> ttl a
(integer) -1

注意:当使用set更新键的时候 ex 设置的过期时间将无效

  1. 获取值 get key
127.0.0.1:6379[1]> get a
"2"
127.0.0.1:6379[1]> get b
(nil)// 不存在将返回 nil
127.0.0.1:6379[1]> get a
"2"
127.0.0.1:6379[1]> get b
(nil)// 不存在将返回 nil
  1. 批量设置值 mset key value [key value...]
  2. 批量获取值mget key [key...]
127.0.0.1:6379[1]> mset b 2 c 3 d 4
OK
127.0.0.1:6379[1]> keys *
1) "b"
2) "a"
3) "d"
4) "c"
127.0.0.1:6379[1]> mget a b c d e
1) "2"
2) "2"
3) "3"
4) "4"
5) (nil)//不存在返回 nil不常用的命令
127.0.0.1:6379[1]> mset b 2 c 3 d 4
OK
127.0.0.1:6379[1]> keys *
1) "b"
2) "a"
3) "d"
4) "c"
127.0.0.1:6379[1]> mget a b c d e
1) "2"
2) "2"
3) "3"
4) "4"
5) (nil)//不存在返回 nil不常用的命令
  1. 计数 incr key
127.0.0.1:6379[1]> incr b
(integer) 3
127.0.0.1:6379[1]> get b
"3"
127.0.0.1:6379[1]> incr b
(integer) 4
127.0.0.1:6379[1]> get b
"4"
127.0.0.1:6379[1]> incr b
(integer) 3
127.0.0.1:6379[1]> get b
"3"
127.0.0.1:6379[1]> incr b
(integer) 4
127.0.0.1:6379[1]> get b
"4"

decr(自减) incrby (增加指定的数值) decrby(减少指定的数值) incrbyfloat (增加浮点数)

127.0.0.1:6379[1]> incrby b 10
(integer) 14
127.0.0.1:6379[1]> get b
"14"
127.0.0.1:6379[1]> decrby b 9
(integer) 5
127.0.0.1:6379[1]> get b
"5"
127.0.0.1:6379[1]> incrbyfloat b 0.5
"5.5"
127.0.0.1:6379[1]> incrby b 10
(integer) 14
127.0.0.1:6379[1]> get b
"14"
127.0.0.1:6379[1]> decrby b 9
(integer) 5
127.0.0.1:6379[1]> get b
"5"
127.0.0.1:6379[1]> incrbyfloat b 0.5
"5.5"
  1. 不常用的命令
  1. 追加值 append key value
127.0.0.1:6379[1]> append a 2
(integer) 2
127.0.0.1:6379[1]> get a
"22"
127.0.0.1:6379[1]> append a 2
(integer) 2
127.0.0.1:6379[1]> get a
"22"
  1. 字符串长度 strlen key
127.0.0.1:6379[1]> strlen a
(integer) 2 // 返回长度
127.0.0.1:6379[1]> strlen a
(integer) 2 // 返回长度
  1. 设置并返回原值 getset key value
127.0.0.1:6379[1]> getset a 1
"22"
127.0.0.1:6379[1]> get a
"1"
127.0.0.1:6379[1]> getset a 1
"22"
127.0.0.1:6379[1]> get a
"1"
  1. 设置指定位置的字符 setrange key 下标 value
127.0.0.1:6379[1]> setrange a 0 2
(integer) 1
127.0.0.1:6379[1]> get a
"2"
127.0.0.1:6379[1]> setrange a 0 2
(integer) 1
127.0.0.1:6379[1]> get a
"2"
  1. 获取部分字符串 getrange key start end
127.0.0.1:6379[1]> set a 123456789
OK
127.0.0.1:6379[1]> get a
"123456789"
127.0.0.1:6379[1]> getrange a 1 4
"2345"
127.0.0.1:6379[1]> set a 123456789
OK
127.0.0.1:6379[1]> get a
"123456789"
127.0.0.1:6379[1]> getrange a 1 4
"2345"
  1. 命令的复杂度

命令

作用

复杂度

set key value

设置单个属性

O(1)

get key

获取单个属性的值

O(1)

del key ...

删除键值

O(k) k是元素个数

mset key value ...

设置多个键值的值

O(k) k是元素个数

mget key...

得到多个键值的值

O(k) k是元素个数

incr key / incrby key


O(1)

decr key / dectby key


O(1)

incrbyfloat key value

增加浮点数

O(1)

append key value

末尾增加

O(1)

strlen key

得到字符串长度

O(1)

setrange key offset value

更新某个位置值

O(1)

getrange key start end

获取一段的值

O(n) n是字符串长度

字符串的内部编码
  1. int :8个字节的长整型
  2. embstr :小于等于39个字节的字符串
  3. raw : 大于39个字节的字符串
使用场景
  1. 缓存功能 ,Redis作为缓存层,MySQL作为储存层 在高并发的请求中我们把用户信息储存到redis中可以快速获取用户信息
  2. 计数我们可以用redis 记录视频的播放次数
  3. 共享session 在分布式web服务中心将用户的session信息用redis集中进行管理,每次用户更新或者查询登录信息时都可以直接去redis 中获取
  4. 限速,可以限制用户手机验证码的频繁获取

哈希

哈希类型是指键值本身又是一个键值对结构,形如value{{key1,value1},{key2 value2}} 就相当于 一个 Java中的类 一个person类中有人的 名字年龄等等一些信息

命令
  1. 设置值 hset key field value
127.0.0.1:6379[1]> hset person name zhangsan
(integer) 1
127.0.0.1:6379[1]> hset person name zhangsan
(integer) 1
  1. 获取值 hget key field
127.0.0.1:6379[1]> hget person name
"zhangsan"  
127.0.0.1:6379[1]> hget person age
(nil)// 不存在返回nil
127.0.0.1:6379[1]> hget person name
"zhangsan"  
127.0.0.1:6379[1]> hget person age
(nil)// 不存在返回nil
  1. 删除 hdel key field [field...]
127.0.0.1:6379[1]> hset person age 12
(integer) 1
127.0.0.1:6379[1]> hset person sex 1
(integer) 1
127.0.0.1:6379[1]> hkeys person  // 查询所有键值
1) "name"
2) "age"
3) "sex"
127.0.0.1:6379[1]> hdel person age sex
(integer) 2
127.0.0.1:6379[1]> hkeys person
1) "name"
127.0.0.1:6379[1]> hdel person city
(integer) 0 // 删除不存在的键的返回值
127.0.0.1:6379[1]> hset person age 12
(integer) 1
127.0.0.1:6379[1]> hset person sex 1
(integer) 1
127.0.0.1:6379[1]> hkeys person  // 查询所有键值
1) "name"
2) "age"
3) "sex"
127.0.0.1:6379[1]> hdel person age sex
(integer) 2
127.0.0.1:6379[1]> hkeys person
1) "name"
127.0.0.1:6379[1]> hdel person city
(integer) 0 // 删除不存在的键的返回值
  1. 计算field 的个数 hlen key
127.0.0.1:6379[1]> hlen person
(integer) 1 // 说明剩余一个
127.0.0.1:6379[1]> hset person city Beijing
(integer) 1
127.0.0.1:6379[1]> hlen person
(integer) 2
127.0.0.1:6379[1]> hlen person
(integer) 1 // 说明剩余一个
127.0.0.1:6379[1]> hset person city Beijing
(integer) 1
127.0.0.1:6379[1]> hlen person
(integer) 2
  1. 批量设置或批量获取
    hmset key field value [...]
    hget key field value [...]
127.0.0.1:6379[1]> hmset student name zhangsan age 21 sex 1
OK
127.0.0.1:6379[1]> hmget student name age sex
1) "zhangsan"
2) "21"
3) "1"
127.0.0.1:6379[1]> hmset student name zhangsan age 21 sex 1
OK
127.0.0.1:6379[1]> hmget student name age sex
1) "zhangsan"
2) "21"
3) "1"
  1. 判断field是否存在 hexists key field
127.0.0.1:6379[1]> hexists student name
(integer) 1 // 存在
127.0.0.1:6379[1]> hexists student address
(integer) 0 // 不存在
127.0.0.1:6379[1]> hexists student name
(integer) 1 // 存在
127.0.0.1:6379[1]> hexists student address
(integer) 0 // 不存在
  1. 获取所有的field hkeys key
127.0.0.1:6379[1]> hkeys student
1) "name"
2) "age"
3) "sex"
127.0.0.1:6379[1]> hkeys student
1) "name"
2) "age"
3) "sex"
  1. 获取所有的value hvals key
127.0.0.1:6379[1]> hvals student
1) "zhangsan"
2) "21"
3) "1"
127.0.0.1:6379[1]> hvals student
1) "zhangsan"
2) "21"
3) "1"
  1. 获取所有的 field-value hgetall key
127.0.0.1:6379[1]> hgetall student
1) "name"
2) "zhangsan"
3) "age"
4) "21"
5) "sex"
6) "1"
127.0.0.1:6379[1]> hgetall student
1) "name"
2) "zhangsan"
3) "age"
4) "21"
5) "sex"
6) "1"
  1. hincrby hincrbyfloat
127.0.0.1:6379[1]> hset student score 50
(integer) 1
127.0.0.1:6379[1]> hincrby student score 1 //后面加上自定义的数值
(integer) 51  // 返回值为更新过后的值
127.0.0.1:6379[1]> hincrbyfloat student score 1.5
"52.5"
127.0.0.1:6379[1]> hget student score
"52.5"
127.0.0.1:6379[1]> hset student score 50
(integer) 1
127.0.0.1:6379[1]> hincrby student score 1 //后面加上自定义的数值
(integer) 51  // 返回值为更新过后的值
127.0.0.1:6379[1]> hincrbyfloat student score 1.5
"52.5"
127.0.0.1:6379[1]> hget student score
"52.5"
  1. 命令复杂度分析

命令

命令作用

复杂度

hset key field value

设置 key 的单个属性的值

O(1)

hget key field value

得到key 的单个属性的值

O(1)

hdel key field ...

批量删除key 的属性

O(k) k是field的个数

hlen key

得到key中属性的个数

O(k) k是field的个数

hmset key field value ...

批量设置key 属性

O(k) k是field的个数

hmget key field ...

批量得到key 属性的值

O(k) k是field的个数

hexists key field

判断key 中的属性是否存在

O(1)

hkeys key

得到所有key中的属性

O(n) n是field的个数

hvals key

得到所有key 中的属性的值

O(n) n是field的个数

hgetall

得到key中所有属性和值

O(1)

hincrby/hincrbyfloat

增加

O(1)

内部编码
  1. ziplist(压缩列表) 当hash 类型元素个数小于hash-max-ziplist-entries配置(默认512个),同时所有值都小于hash-max-ziplist-value配置(默认64字节)Redis会使用ziplist作为hash的内部实现 ziplist 比较节省内存
  2. hashtable (哈希表) 当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,hashtable 的读写速度为O(1)
使用场景
  1. 利用Redis的hash储存用户的属性,这样更加直观,操作时更加便捷

列表

列表类型是用来储存多个有序字符串,列表中的元素可以通过下标来获取,列表中的元素可以重复,一个列表最多可以储存232 -1 个元素 list 可以充当队列或者栈使用

命令

  1. 在某个元素之前或者之后插入 linsert key before/after pivot value
127.0.0.1:6379[1]> linsert list1 before 6 7
(integer) 7
127.0.0.1:6379[1]> lrange list1 0 -1
1) "7"
2) "6"
3) "5"
4) "4"
5) "1"
6) "2"
7) "3"
127.0.0.1:6379[1]> linsert list1 after 3 4
(integer) 8
127.0.0.1:6379[1]> lrange list1 0 -1
1) "7"
2) "6"
3) "5"
4) "4"
5) "1"
6) "2"
7) "3"
8) "4"
127.0.0.1:6379[1]> linsert list1 before 6 7
(integer) 7
127.0.0.1:6379[1]> lrange list1 0 -1
1) "7"
2) "6"
3) "5"
4) "4"
5) "1"
6) "2"
7) "3"
127.0.0.1:6379[1]> linsert list1 after 3 4
(integer) 8
127.0.0.1:6379[1]> lrange list1 0 -1
1) "7"
2) "6"
3) "5"
4) "4"
5) "1"
6) "2"
7) "3"
8) "4"
  1. 查找获取指定范围的列表 lrange list1 start end
127.0.0.1:6379[1]> lrange list1 1 3  // 类似于Python的切片
1) "6"
2) "5"
3) "4"
127.0.0.1:6379[1]> lrange list1 1 3  // 类似于Python的切片
1) "6"
2) "5"
3) "4"
  1. 获取列表指定索引下标的元素 lindex key index
127.0.0.1:6379[1]> lindex list1 0
"7"
127.0.0.1:6379[1]> lindex list1 0
"7"
  1. 获取列表长度 llen key
127.0.0.1:6379[1]> llen list1
(integer) 8
127.0.0.1:6379[1]> llen list1
(integer) 8
  1. 删除元素 lpop/rpop key
127.0.0.1:6379[1]> lpop list1
"7"
127.0.0.1:6379[1]> rpop list1
"4"
127.0.0.1:6379[1]> lpop list1
"7"
127.0.0.1:6379[1]> rpop list1
"4"
  1. 删除指定元素 lrem key count
  • count>0 从左到右,删除最多count 个元素
  • count<0 从右到左,删除最多count个元素
  • count=0 删除所有
127.0.0.1:6379[1]> lpush list1 1 1 1 1
(integer) 10
127.0.0.1:6379[1]> rpush list1 1 1 1 1
(integer) 14
127.0.0.1:6379[1]> lrange list1 0 -1
 1) "1"
 2) "1"
 3) "1"
 4) "1"
 5) "6"
 6) "5"
 7) "4"
 8) "1"
 9) "2"
10) "3"
11) "1"
12) "1"
13) "1"
14) "1"
127.0.0.1:6379[1]> lrem list1 4 1
(integer) 4
127.0.0.1:6379[1]> lrange list1 0 -1
 1) "6"
 2) "5"
 3) "4"
 4) "1"
 5) "2"
 6) "3"
 7) "1"
 8) "1"
 9) "1"
10) "1"
127.0.0.1:6379[1]> lrem list1 -4 1
(integer) 4
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
4) "1"
5) "2"
6) "3"
127.0.0.1:6379[1]> lrem list1 0 1
(integer) 1
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
4) "2"
5) "3"
  1. 按照范围修剪列表 ltrim key start end
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
4) "2"
5) "3"
127.0.0.1:6379[1]> ltrim list1 0 2
OK
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
4) "2"
5) "3"
127.0.0.1:6379[1]> ltrim list1 0 2
OK
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
  1. 修改指定索引下标的元素 lset key index newValue
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
127.0.0.1:6379[1]> lset list1 0 1
OK
127.0.0.1:6379[1]> lrange list1 0 -1
1) "1"
2) "5"
3) "4"
127.0.0.1:6379[1]> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
127.0.0.1:6379[1]> lset list1 0 1
OK
127.0.0.1:6379[1]> lrange list1 0 -1
1) "1"
2) "5"
3) "4"
  1. 阻塞时弹出操作
  • blpop/ brpop key [key ...] timeout
    timeout 表示阻塞时间
  1. 如果列表为空 timeout ==3 那么客户端1会等三秒返回, 如果在此期间另一个客户端 客户端2从中添加一个元素后,客户端1会立即返回客户端2添加的元素
  2. 如果timeout==0 当前list 为空 就会一直等待下去 直到获取到值为止
  3. 如果不为空客户端1会立即返回
    如图所示
客户端1:127.0.0.1:6379> brpop t 0
1) "t"
2) "1"
(6.67s) // 等待的时间
客户端1:127.0.0.1:6379> brpop t 0
1) "t"
2) "1"
(6.67s) // 等待的时间
客户端2:127.0.0.1:6379> lpush t 1
(integer) 1
客户端2:127.0.0.1:6379> lpush t 1
(integer) 1
  1. 如果有多个客户端执行brpop 会按照 执行brpop命令的先后顺序 得到元素
  2. 命令复杂度分析

命令

命令作用

时间复杂度

rpush key value ...

列表右侧添加多个元素

O(k) k为添加元素的个数

lpush key value ...

列表左侧添加多个元素

O(k) k为添加元素的个数

linsert key after/before pivot value

在列表某个元素之前后插入元素

O(n) n为pivot到列表头或尾的距离

lrange key start end

查找指定范围的值

O(s+n) s是start偏移量,n是start到end的范围

lindex key lindex

查找对应下标的值

O(n) n是索引的偏移量

llen key

获取列表的长度

O(1)

lpop

从左侧删除

O(1)

rpop

从右侧删除

O(1)

lrem key count value

删除 一些元素

O(n) n是列表长度

ltrim key start end

剪切列表

O(n) n为要裁剪的元素总数

lset key index value

修改指定位置的元素的值

O(n) 你是索引偏移量

brpop blpop

阻塞弹出操作

O(1)

内部编码
1. ziplist(压缩列表) 当hash 类型元素个数小于hash-max-ziplist-entries配置(默认512个),同时所有值都小于hash-max-ziplist-value配置(默认64字节)Redis会使用ziplist作为hash的内部实现 ziplist 比较节省内存
2. linkedlist(链表)当列表类型无法满足ziplist的条件时,Redis会选用linkedlist 作为内部实现
3. Redis3.2以上的 版本提供了quicklist 是ziplist和linkedlist优势的结合
使用场景
1. 消息队列 redis的lpush+brpop 命令组合可以实现阻塞队列,生产者 负责生产元素,消费者客户端使用brpop命令阻塞式的“抢:列表内部的元素,多个客户端保证了消费的复杂均衡
2. 文章列表  每篇文章可以用hash 存储 我们可以把文章放进列表里 分页获取文章列表

集合

集合也是用来保存多个字符串元素,但和列表不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标来获取元素,一个集合最多储存 2 32 -1个元素,集合支持 交集,并集,差集

命令
  1. 添加元素 sadd key element
127.0.0.1:6379[1]> sadd myset1 1 2 3
(integer) 3 //返回插入成功的数量
127.0.0.1:6379[1]> sadd myset1 3
(integer) 0
127.0.0.1:6379[1]> sadd myset1 1 2 3
(integer) 3 //返回插入成功的数量
127.0.0.1:6379[1]> sadd myset1 3
(integer) 0
  1. 删除元素 srem key element
127.0.0.1:6379[1]> srem myset1 1 2 3
(integer) 3
127.0.0.1:6379[1]> srem myset1 1 2 3
(integer) 3
  1. 计算元素个数 scard key
(integer) 0
127.0.0.1:6379[1]> sadd myset1  1 2 3
(integer) 3
127.0.0.1:6379[1]> scard myset1
(integer) 3
(integer) 0
127.0.0.1:6379[1]> sadd myset1  1 2 3
(integer) 3
127.0.0.1:6379[1]> scard myset1
(integer) 3
  1. 判断元素是否存在集合之中 sismember key element
127.0.0.1:6379[1]> sismember myset1 1
(integer) 1
127.0.0.1:6379[1]> sismember myset1 4
(integer) 0
127.0.0.1:6379[1]> sismember myset1 1
(integer) 1
127.0.0.1:6379[1]> sismember myset1 4
(integer) 0
  1. 随机从集合返回指定个数元素 srandmember key [count] // count 默认为1
127.0.0.1:6379[1]> srandmember myset1 2
1) "1"
2) "3"
127.0.0.1:6379[1]> srandmember myset1 2
1) "1"
2) "3"
  1. 从集合中随机弹出元素 :spop key
127.0.0.1:6379[1]> spop myset1
"1"
127.0.0.1:6379[1]> spop myset1
"1"
  1. 获取所有元素: smembers key
127.0.0.1:6379[1]> smembers myset1
1) "2"
2) "3"
127.0.0.1:6379[1]> smembers myset1
1) "2"
2) "3"
  1. 求多个集合的交集: sinter key ... // 后面可以跟多个键
127.0.0.1:6379[1]> sadd myset2 2 3 4
(integer) 3
127.0.0.1:6379[1]> smembers myset1
1) "2"
2) "3"
127.0.0.1:6379[1]> smembers myset2
1) "2"
2) "3"
3) "4"
127.0.0.1:6379[1]> sinter myset1 myset2
1) "2"
2) "3"
127.0.0.1:6379[1]> sadd myset2 2 3 4
(integer) 3
127.0.0.1:6379[1]> smembers myset1
1) "2"
2) "3"
127.0.0.1:6379[1]> smembers myset2
1) "2"
2) "3"
3) "4"
127.0.0.1:6379[1]> sinter myset1 myset2
1) "2"
2) "3"
  1. 求多个集合的并集 : sunion key ...
127.0.0.1:6379[1]> sadd myset1 1
(integer) 1 // 为了好区分 在 set中插入一个1
127.0.0.1:6379[1]> sunion myset1 myset2
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379[1]> sadd myset1 1
(integer) 1 // 为了好区分 在 set中插入一个1
127.0.0.1:6379[1]> sunion myset1 myset2
1) "1"
2) "2"
3) "3"
4) "4"
  1. 求多个集合的差集 : sdiff key...
127.0.0.1:6379[1]> sdiff myset1 myset2
1) "1"
127.0.0.1:6379[1]> sdiff myset1 myset2
1) "1"
  1. 将集合的 交并差结果保存 : sinterstore(交)/suinonstore(并)/sdiffstore(差)+ 保存的键的名字 key ...
127.0.0.1:6379[1]> sinterstore  mysetinter myset1 myset2
(integer) 2
127.0.0.1:6379[1]> smembers mysetinter
1) "2"
2) "3"
// 剩下两个不再掩演示
127.0.0.1:6379[1]> sinterstore  mysetinter myset1 myset2
(integer) 2
127.0.0.1:6379[1]> smembers mysetinter
1) "2"
2) "3"
// 剩下两个不再掩演示
  1. 命令的时间复杂度

命令

命令作用

时间复杂度

sadd key element...

添加元素

O(k) k是元素个数

srem key element

删除元素

O(k) k是元素个数

scard key

计算元素数量

O(1)

sismember key element

元素是否存在集合

O(1)

srandmember key count

随机返回指定个数元素

O(count)

spop key

弹出元素

O(1)

smembers key

所有元素

O(n) n是元素个数

sinter key ... /sinterstore

交集

O(m*k) m 集合中元素最少的 k集合中元素最多的

suinon key ... /suinonstroe

并集

O(k) k是多个集合元素个数和

sdiff key ... /sdiffstore

差集

O(k) k是多个集合元素个数和

内部编码
  1. intset(整数集合) 当集合中的元素都是整数,且元素个数小于set-max-intset-entries 配置(默认512个) redis会选用intset 作为内部实现,节省内存的使用
  2. hashtable (哈希表) 当集合类型无法满足时 使用hashtable
使用场景
  1. 标签 用户可能对娱乐,体育比较感兴趣,另一个用户对新闻,动漫感兴趣,这些兴趣都是标签,有了这些数据 可以得到喜欢同一个标签的人,以及用户的共同喜好,可以用这些数据增强用户粘度和用户体验

有序集合

命令
  1. 添加元素 zadd key score member [score member...]
127.0.0.1:6379[1]> zadd rank1 1 zhangsan 2 lisi 3 wangwu
(integer) 3 //成功添加的个数
127.0.0.1:6379[1]> zadd rank1 1 zhangsan 2 lisi 3 wangwu
(integer) 3 //成功添加的个数
  1. 计算成员个数 :zcard key
127.0.0.1:6379[1]> zcard rank1
(integer) 3
127.0.0.1:6379[1]> zcard rank1
(integer) 3
  1. 计算某个成员的分数:zscore key member
127.0.0.1:6379[1]> zscore rank1 zhangsan
"1"
127.0.0.1:6379[1]> zscore rank1 zhangsan
"1"
  1. 计算成员的排名 zrank/zrevrank key member
127.0.0.1:6379[1]> zrank rank1 zhangsan
(integer) 0
127.0.0.1:6379[1]> zrevrank rank1 zhangsan
(integer) 2
127.0.0.1:6379[1]> zrank rank1 zhangsan
(integer) 0
127.0.0.1:6379[1]> zrevrank rank1 zhangsan
(integer) 2
  1. 删除成员 zrem key member [member ...]
127.0.0.1:6379[1]> zrem rank1 zhangsan
(integer) 1
127.0.0.1:6379[1]> zrem rank1 zhangsan
(integer) 1
  1. 增加成员的分数 zincrby key increment member
127.0.0.1:6379[1]> zincrby rank1 10 lisi
"12" //返回增加后的数值
127.0.0.1:6379[1]> zincrby rank1 10 lisi
"12" //返回增加后的数值
  1. 返回指定排名范围的成员: zrange/zrevrange key start end [withscores]
127.0.0.1:6379[1]> zrange rank1 1 3 withscores // withscores 会带上分数
1) "wangwu"
2) "3"
3) "maliu"
4) "4"
5) "lisi"
6) "12"
127.0.0.1:6379[1]> zrevrange  rank1 1 3
1) "maliu"
2) "wangwu"
3) "zhangsan"
127.0.0.1:6379[1]> zrange rank1 1 3 withscores // withscores 会带上分数
1) "wangwu"
2) "3"
3) "maliu"
4) "4"
5) "lisi"
6) "12"
127.0.0.1:6379[1]> zrevrange  rank1 1 3
1) "maliu"
2) "wangwu"
3) "zhangsan"
  1. 返回指定分数范围的成员 :zrangebyscore/zrevrangebyscore key min/max max/min [withscores] [limit offset count // 限制输出的起始位置和个数]
127.0.0.1:6379[1]> zrangebyscore rank1 1 3 withscores
1) "zhangsan"
2) "1"
3) "wangwu"
4) "3"
127.0.0.1:6379[1]> zrevrangebyscore rank1 4 3 withscores
1) "maliu"
2) "4"
3) "wangwu"
4) "3"
127.0.0.1:6379[1]> zrangebyscore rank1 1 3 withscores
1) "zhangsan"
2) "1"
3) "wangwu"
4) "3"
127.0.0.1:6379[1]> zrevrangebyscore rank1 4 3 withscores
1) "maliu"
2) "4"
3) "wangwu"
4) "3"
  1. 返回指定分数范围成员个数 zcount key min max
127.0.0.1:6379[1]> zcount rank1 1 3
(integer) 2
127.0.0.1:6379[1]> zcount rank1 1 3
(integer) 2
  1. 删除指定排名内的升序元素 zremrangebyrank key start end
127.0.0.1:6379[1]> zremrangebyrank rank1 1 2
(integer) 2
127.0.0.1:6379[1]> zrange rank1 0 10
1) "zhangsan"
2) "lisi"
127.0.0.1:6379[1]> zremrangebyrank rank1 1 2
(integer) 2
127.0.0.1:6379[1]> zrange rank1 0 10
1) "zhangsan"
2) "lisi"
  1. 删除指定分数范围的成员 zremrangebyscore key min max
127.0.0.1:6379[1]> zremrangebyscore rank1 10 14
(integer) 1
127.0.0.1:6379[1]> zrange rank1 0 10
1) "zhangsan"
127.0.0.1:6379[1]> zremrangebyscore rank1 10 14
(integer) 1
127.0.0.1:6379[1]> zrange rank1 0 10
1) "zhangsan"
  1. 交集 zinterstore destination numkeys key [key...] [weights weight [weight...]] [aggregate sum|max|min]
    destination :交集计算结果保存的键
    numkeys:需要做交集计算的个数
    key[key..] 需要做交集计算的键
    weights weight [weight ...] 每个键的权重,在做交集计算
127.0.0.1:6379[1]> zrange rank1 0 -1 withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
5) "lihua"
6) "10"
127.0.0.1:6379[1]> zrange rank2 0 -1 withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "3"
5) "xiaohong"
6) "5"
7) "xiaoming"
8) "6"
127.0.0.1:6379[1]> zinterstore interrank1andrank2 2  rank1 rank2
(integer) 2
127.0.0.1:6379[1]> zrange interrank1andrank2 0 -1
1) "zhangsan"
2) "lisi"
127.0.0.1:6379[1]> zrange interrank1andrank2 0 -1 withscroes
(error) ERR syntax error
127.0.0.1:6379[1]> zrange interrank1andrank2 0 -1 withscores
1) "zhangsan"
2) "2"
3) "lisi"
4) "5"
127.0.0.1:6379[1]> zinterstore interrank 2 rank1 rank2 weights 1 0.5 aggregate max // rank1 的 score*1.0 rank2 的score*0.5 然后取两者中最大的
(integer) 2
127.0.0.1:6379[1]> zrange interrank 0 -1 withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
127.0.0.1:6379[1]> zrange rank1 0 -1 withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
5) "lihua"
6) "10"
127.0.0.1:6379[1]> zrange rank2 0 -1 withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "3"
5) "xiaohong"
6) "5"
7) "xiaoming"
8) "6"
127.0.0.1:6379[1]> zinterstore interrank1andrank2 2  rank1 rank2
(integer) 2
127.0.0.1:6379[1]> zrange interrank1andrank2 0 -1
1) "zhangsan"
2) "lisi"
127.0.0.1:6379[1]> zrange interrank1andrank2 0 -1 withscroes
(error) ERR syntax error
127.0.0.1:6379[1]> zrange interrank1andrank2 0 -1 withscores
1) "zhangsan"
2) "2"
3) "lisi"
4) "5"
127.0.0.1:6379[1]> zinterstore interrank 2 rank1 rank2 weights 1 0.5 aggregate max // rank1 的 score*1.0 rank2 的score*0.5 然后取两者中最大的
(integer) 2
127.0.0.1:6379[1]> zrange interrank 0 -1 withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
  1. 并集 zunionstore destination numkeys key [key...] [weights weight [weight...]] [aggregate sum|max|min]
destination :交集计算结果保存的键
numkeys:需要做交集计算的个数
key[key..] 需要做交集计算的键
weights weight [weight ...] 每个键的权重,在做交集计算

  1. 代码不做演示和 交集一样
  2. 命令复杂度分析

命令

作用

时间复杂度

zadd key score member ...

批量添加

O(k*logn) k是添加成员个数 n是当前集合成员个数

zcard key

计算成员个数

O(1)

zscore key member

计算成员的分数

O(1)

zrank/zrevrank key member

查看成员的rank

O(logn) n当前有序集合成员个数

zrem key member

删除成员

O(k*logn) k删除成员个数 n当前集合个数

zincrby key increment member

增长

O(logn)n当前集合个数

zrange/zrevrange key satrt end withscores

返回指定rank范围成员

O(logn+k) k要获取的成员个数 n集合的成员个数

zrangebyscore/zrevrangebyscore key min/max max/min [withscores]

返回指定分数范围成员

O(logn+k) k要获取的成员个数 n集合的成员个数

zcount key min max

计算分数范围的成员个数

O(logn) n当前集合成员个数

zremrangebyrank key start end

删除指定排名成员

O(logn+k) k要删除的成员个数 n集合的成员个数

zremrangebyscore key min max

删除指定分数成员

O(logn+k) k要删除的成员个数 n集合的成员个数

zinterstore/zunionstroe destination numkeys key [key...]

交集/并集

O(n*k)+O(m*logm) n最小集合的成员个数 k有序集合的个数 m是结果集中成员个数/ O(n)+O(m*logm) n所有集合成员个数 m是结果集中成员个数

内部编码
  1. ziplist ziplist(压缩列表) 当hash 类型元素个数小于zset-max-ziplist-entries配置(默认128个),同时所有值都小于hash-max-ziplist-value配置(默认64字节)Redis会使用ziplist作为hash的内部实现 ziplist 比较节省内存
  2. skiplist(跳表)
使用场景
  1. 热度排行榜
  2. 用户点赞数

其他

  1. 键重命名 rename key newkey
    如果当前键名已存在会覆盖掉之前的键
    redis提供了renamenx 命令 ex:renamenx key value
  1. 重命名期间执行del删除旧键时,如果键对应的值较大,会存在阻塞
  1. 随机返回一个键 randomkey
  2. persist 命令可以消除 键的过期时间 persist key
  3. 对于字符串类型在进行set 时 会去掉过期时间
  4. scan 渐进式遍历键 scan x
127.0.0.1:6379[1]> scan 0
1) "3"
2)  1) "rank1"
    2) "interrank"
    3) "list1"
    4) "d"
    5) "person"
    6) "myset2"
    7) "a"
    8) "interrank1andrank2"
    9) "mysetinter"
   10) "mtyset1"
   11) "myset1"
127.0.0.1:6379[1]> scan 3
1) "0"
2) 1) "c"
   2) "b"
   3) "rank2"
   4) "student"
127.0.0.1:6379[1]> keys *
 1) "rank1"
 2) "d"
 3) "person"
 4) "c"
 5) "interrank1andrank2"
 6) "mysetinter"
 7) "b"
 8) "myset2"
 9) "a"
10) "interrank"
11) "list1"
12) "mtyset1"
13) "myset1"
14) "rank2"
15) "student"
127.0.0.1:6379[1]> scan 0
1) "3"
2)  1) "rank1"
    2) "interrank"
    3) "list1"
    4) "d"
    5) "person"
    6) "myset2"
    7) "a"
    8) "interrank1andrank2"
    9) "mysetinter"
   10) "mtyset1"
   11) "myset1"
127.0.0.1:6379[1]> scan 3
1) "0"
2) 1) "c"
   2) "b"
   3) "rank2"
   4) "student"
127.0.0.1:6379[1]> keys *
 1) "rank1"
 2) "d"
 3) "person"
 4) "c"
 5) "interrank1andrank2"
 6) "mysetinter"
 7) "b"
 8) "myset2"
 9) "a"
10) "interrank"
11) "list1"
12) "mtyset1"
13) "myset1"
14) "rank2"
15) "student"
  1. 清空数据库
    flushdb/flushall
    前者清空当前数据库 后者全部清空