Redis学习

Redis 介绍

Redis是一个非常快的键/值存储,在某些方面类似于memcached。Redis可存储的数据结构有:

  • 字符串(strings)
  • 列表(lists)
  • 哈希映射(hash maps)
  • 集合(sets)
  • 排序集合(sorted sets)。

Redis还可以作为一个轻量级的发布/订阅或消息队列系统。Redis 通常与其他NoSQL技术结合在一起,通常用作缓存层。因为Redis提供网络可用的数据结构,所以它非常灵活,能够解决各种问题。

一句话概括:Redis是一个通过网络公开的数据结构的集合。
Redis 官网:https://redis.io/

安装Redis

brew install redis
安装路径:/usr/local/Cellar/
配置文件路径:/usr/local/etc/redis.conf

Mac 启动/关闭Redis

  • 方式一
    启动:brew services start redis
    关闭:brew services stop redis
  • 方式二
    启动:redis-server /usr/local/etc/redis.conf
    关闭:redis-cli shutdown 或者 sudo pkill redis-server

连接Redis

redis-cli -h 127.0.0.1 -p 6379 --raw
–raw参数可以显示中文的值。

Jedis 介绍

Jedis 是一个非常小而健全的 Redis java 客户端,易于使用,完全兼容redis 2.8.x, 3.x.x 及以上版本。
Jedis GitHub介绍:https://github.com/redis/jedis
其他Redis客户端 https://redis.io/clients#java

Jedis 操作 Redis 数据库

创建Maven 项目Jedis
Maven创建Jedis项目

添加 Jedis 和单元测试依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>

创建单元测试类JedisDemo1
JedisDemo1

单实例测试

/**
 * 单实例测试
 */
@Test
public void demo1(){
    // 1.设置 IP 和端口号
    Jedis jedis = new Jedis("127.0.0.1", 6379);
    // 2.保存数据
    jedis.set("name", "张三");
    // 3.获取数据
    String value = jedis.get("name");
    System.out.println(value);
    // 4.释放资源
    jedis.close();
}

连接池方式连接

/**
 * 连接池方式
 */
@Test
public void demo2(){
    // 创建连接池配置对象
    JedisPoolConfig config = new JedisPoolConfig();
    // 设置最大链接数
    config.setMaxTotal(30);
    // 设置最大空闲连接数
    config.setMaxIdle(10);
    // 获取连接池
    JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379);

    Jedis jedis = null;
    try {
        // 通过连接池获取连接
        jedis = jedisPool.getResource();
        // 保存数据
        jedis.set("company", "远石");
        // 获取数据
        String value = jedis.get("company");
        System.out.println(value);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(jedis != null){
            jedis.close();
        }
        if(jedisPool != null){
            jedisPool.close();
        }
    }
}

程序输出:
程序输出2

Reids数据结构

key定义注意点:

Redis key是二进制安全的,这意味着可以使用任何二进制序列作为key,从字符串“foo”到JPEG文件的内容都可以作为key。空字符串也是一个有效的key。

  • 不要太长,不超过1024字节,会降低查找效率,占用内存。
  • 不要太短,影响可读性。
    例如:key命名为 u1000flw 很难key的含义
    若命名为 user:1000:followers ,就很容易知道key的含义,提高可读性
  • 统一命名规范。。
    例如:
    使用 类型:id 作为key,user:1000
    使用.或者-作为做个字段的分隔符,comment🔢reply.to 或者comment🔢reply-to
  • key最大不超过512MB。

strings类型

strings是Redis最简单的值类型。字符串类型有很多用户,例如缓存HTML代码片段或者页面。

127.0.0.1:6379> set company 远石
OK
127.0.0.1:6379> get company
远石
127.0.0.1:6379>
set赋值: set key value

给指定的key赋值字符串操作。如果key不存在直接赋值,如果key存在覆盖已有值(跟原来值类型无关)。

值可以是任意类型的字符串,包括二进制数据。例如可以一张图片当做值进行存储,最大不超过512MB。

get取值: get key

获取指定key的字符串值。

set扩展参数: set key value [nx|xx]
  • nx:如果key已存在,则赋值失败。
127.0.0.1:6379> set company 远石科技 nx

127.0.0.1:6379> get company
远石
127.0.0.1:6379>
  • xx:如果key已存在,则赋值成功,否则赋值失败。
127.0.0.1:6379> set company 远石科技 xx
OK
127.0.0.1:6379> get company
远石科技
127.0.0.1:6379>
原子增量

可以对存储的string值做一些运算操作。

127.0.0.1:6379> set counter 100
OK
127.0.0.1:6379> incr counter
101
127.0.0.1:6379> incr counter
102
127.0.0.1:6379> incrby counter 50
152
127.0.0.1:6379>
incr

将字符串值转换为整形,并增加1作为新值。如果值不能转换为整形,会返回错误。如果key不存在,默认值为0,然后执行增加操作。此操作仅限于64位有符号整数。

incrby

增加指定的数。

类似的命令还有:

  • decr: 将值减1。
  • decrby:将值减去指定的数。
127.0.0.1:6379> decr counter
151
127.0.0.1:6379> decrby counter 50
101
127.0.0.1:6379> set counter 234293482390480948029348230948
OK
127.0.0.1:6379> decr counter
ERR value is not an integer or out of range

127.0.0.1:6379>

原子操作意味着,不会存在多个客户端同时操作同一个key。
例如key值为10,客户端1和客户端2同时执行incr操作,key的最终结果只会是12。

getset

为指定的key设置新值,返回旧值。例如:当网站有新访问者时使用incr增加1,每隔一个小时收集一次新访问者数量,可以每隔一个小时执行一次getset counter 0,返回这一个小时新增数量,并将新增数量设置为0。

127.0.0.1:6379> set counter 100
OK
127.0.0.1:6379> incr counter
101
127.0.0.1:6379> getset counter 0
101
127.0.0.1:6379>

一次设置或获取多个key的值,可以减少延迟。

127.0.0.1:6379> mset a 10 b 20 c 30
OK
127.0.0.1:6379> mget a b c
10
20
30
127.0.0.1:6379>

使用 MGET 时,Redis 将返回一个值数组。

exists

判断key是否存在,存在返回1,不存在返回0

127.0.0.1:6379> set token "abcdefg"
OK
127.0.0.1:6379> exists token
1
127.0.0.1:6379> exists access:token
0
del

删除key和对应的值,key存在返回1,不存在返回0。

127.0.0.1:6379> del token
1
127.0.0.1:6379> del access:token
0
127.0.0.1:6379>
type

返回执行key的值类型,key不存在返回none。

127.0.0.1:6379> set access:token abcdefgh
OK
127.0.0.1:6379> type access:token
string
127.0.0.1:6379> del access:token
1
127.0.0.1:6379> type access:token
none
127.0.0.1:6379> set counter 100
OK
127.0.0.1:6379> type counter
string
127.0.0.1:6379>

即使是整数也以字符串形式存储。

expire

为指定的key设置有效时长,单位秒。时间到了之后自动删除key和value。

127.0.0.1:6379> set access:token "abcdefg123"
OK
127.0.0.1:6379> ttl access:token
-1
127.0.0.1:6379> get access:token
abcdefg123
127.0.0.1:6379> expire access:token 5
1
127.0.0.1:6379> ttl access:token
3
127.0.0.1:6379> get access:token

127.0.0.1:6379>

set赋值操作会删除有效时长。类似的操作还有del,getset等与存储相关的命令。

127.0.0.1:6379> set jwt:token "123" ex 30
OK
127.0.0.1:6379> ttl jwt:token
27
127.0.0.1:6379> set jwt:token "456"
OK
127.0.0.1:6379> ttl jwt:token
-1
127.0.0.1:6379>
ttl

查看指定key的有效时长。

lists类型

Redis 的lists是基于链表实现的,意味着不管lists里面有多少数据,在lists开头或者结尾插入数据所消耗的时间是一样的。
基于链表实现的lists缺点是通过索引访问元素速度很慢。
基于链表实现是因为需要非常快速的向很长lists中插入数据。
如果要获取一大段中间的元素,可以使用sorted sets。

lpush

将指定的值插入到列表的头部(左边),如果key不存在就先创建一个空list,然后再插入。如果指定了多个值,一个一个的插入,后面插入的会再最前面。如果key对应的值不是list会报错。

127.0.0.1:6379> lpush nameList 张三
1
127.0.0.1:6379>
rpush

将指定的值插入到列表的尾部(后边)。

127.0.0.1:6379> rpush nameList 李四 王五
3
127.0.0.1:6379> lpush nameList 老大 老二
5
127.0.0.1:6379>
lrange

抽取列表指定范围的元素。两个索引参数:第一个元素的索引,最后一个元素的索引。-1表示最有一个元素,-2表示倒数第二个元素。

127.0.0.1:6379> lrange nameList 0 -1
老二
老大
张三
李四
王五
127.0.0.1:6379>
rpop

返回列表中最后一个(最右边)元素,并从列表中删除这个元素。

127.0.0.1:6379> rpop nameList
王五
127.0.0.1:6379> lrange nameList 0 -1
老二
老大
张三
李四
127.0.0.1:6379>
lpop

返回列表中第一个(最左边)元素,并从列表中删除这个元素。

127.0.0.1:6379> lpop nameList
老二
127.0.0.1:6379> lrange nameList 0 -1
老大
张三
李四
127.0.0.1:6379>

没有元素时,返回null

127.0.0.1:6379> lpop nameList
老大
127.0.0.1:6379> lpop nameList
张三
127.0.0.1:6379> lpop nameList
李四
127.0.0.1:6379> lpop nameList

127.0.0.1:6379>
lists的常用案列

lists可以用在很多地方,下面是两个非常有代表性的案列:

  • 记录用户提交到网络的最后更新。
  • 进程之间通信,使用生产者消费者模式。生产者向lists添加元素,消费者消费这些元素,执行一些操作操作。

例如Ruby的resque和sidekq库底层使用Reids来实现后台任务。
Twitter将用户提交的最新推文放到Redis lists中。
案列描述:假如你的主页要展示用户发布的最新照片。

  • 用户每提交一个照片,我们使用lpush把图片id存入lists中。
  • 当用户访问主页时,我们使用lrange 0 9来展示最新的10条数据。
有限制的lists

有的时候,我们只想用lists来存储最新的条目,不管他们是什么:数据更新、日志或者其他任何东西。
我们可以使用lists作为受限集合,只记住最新的N个项目,使用ltrim命令丢弃所有就的项目。
ltrim类似与lrange,但ltrim不显示指定范围内的元素,而是将这个范围设置为新的lists值。范围外的元素都将被删除。

127.0.0.1:6379> rpush mylist 1 2 3 4 5
5
127.0.0.1:6379> ltrim mylist 0 2
OK
127.0.0.1:6379> lrange mylist 0 -1
1
2
3
127.0.0.1:6379>

ltrim只从索引0到2获取lists元素,其他元素都删除。

阻塞lists

lists可以作为队列使用,作为进程间的通信模块:阻塞操作。
例如可以用一个进程向lists中添加元素,然后使用不同的进程来处理这些元素。这是常见的生产者消费者设置,可以使用下面的方式简单实现:

  • 生产者使用lpush将元素放入lists
  • 消费者使用rpop从lists中取出元素。

有时列表为空,没有什么需要处理的,那么消费者使用rpop一直返回null。可以使用轮询的方式让消费者等待一段时间再去rpop获取数据,但这种方式有缺点:

  • Redis和客户端一直处理无用的命令,列表没空,根本不需要要做任何处理。
  • 消费者收到null之后,会等待一段时间,如果马上有新的数据存放lists中,消费者不能马上获取到数据,会有延迟。

所以Redis提供了brpop和blpop命令,如果列表为空,它们就会堵塞。只有当有一个新元素添加到列表中,或者达到用户指定的超时时间,它们才会返回结果。

127.0.0.1:6379> lpush mylist 1 2 3 4 5
5
127.0.0.1:6379> blpop mylist 10
mylist
5
127.0.0.1:6379>

等待读取列表中的元素,如果10秒后仍然没有元素,就返回。如果设置为0就一直等待有元素才返回。
可以同时指定多个列表,在多个列表上等待。直到有列表收到元素时返回。前面的列表先返回。

127.0.0.1:6379> lpush mylist3 list3:1 list3:2 list3:3 list3:4 list3:5
5
127.0.0.1:6379> lpush mylist4 list4:1 list4:2 list4:3 list4:4 list4:5
5
127.0.0.1:6379> lpush mylist2 list2:1 list2:2 list2:3 list2:4 list2:5
5
127.0.0.1:6379> blpop mylist3 mylist2 mylist4 5
mylist3
list3:5
127.0.0.1:6379> blpop mylist3 mylist2 mylist4 5
mylist3
list3:4
127.0.0.1:6379> blpop mylist4 mylist3 mylist2 5
mylist4
list4:5
127.0.0.1:6379> blpop mylist4 mylist3 mylist2 5
mylist4
list4:4

brpop/blpop注意事项:

  • 阻塞客户端是有序的。有多个客户端堵塞时,当列表有元素时,第一个阻塞的客户端优先获得数据。
  • 返回值包含两个元素的数组,一个是键的名称,一个是元素值。因为可以阻塞等待多个列表中的元素,需要标明是从哪个列表返回的元素。
  • 如果超时没有获得元素,就返回null。

关于更多的列表和阻塞操作,可以查看命令:lmove、blmove。

关于自动创建和删除键

以下3个规则适用于lists、Streams、 Sets、 Sorted Sets 和 hash。

  • 当向聚合数据类型添加元素时,如果键不存在,就在添加元素之前创建一个空的聚合数据类型。
    127.0.0.1:6379> del mylist
    0
    127.0.0.1:6379> lpush mylist 1 2 3
    3
    127.0.0.1:6379>
  • 当从聚合数据类型中删除元素时,如果值为空,就删除键。Stream数据类型除外。
    127.0.0.1:6379> exists mylist
    1
    127.0.0.1:6379> lpop mylist
    3
    127.0.0.1:6379> lpop mylist
    2
    127.0.0.1:6379> lpop mylist
    1
    127.0.0.1:6379> exists mylist
    0
    127.0.0.1:6379>
  • 使用只读命令,或者删除命令,总是返回的相同的结果,就好像键保存的空聚合类型
        127.0.0.1:6379> del mylist
        0
        127.0.0.1:6379> llen mylist
        0
        127.0.0.1:6379> lpop mylist

        127.0.0.1:6379>

Hashes类型

Hash类型是一个包含多个键值对的散列,可以用来存放对象,存放的字段数量没有限制。

hmset

一次可以存放多个键值对。

127.0.0.1:6379> hmset user:1000 username admin birthday "1995-01-01 23:11:14" authorized 1
OK
127.0.0.1:6379> hget user:1000 username
admin
127.0.0.1:6379> hget user:1000 birthday
1995-01-01 23:11:14
127.0.0.1:6379> hgetall user:1000
username
admin
birthday
1995-01-01 23:11:14
authorized
1
127.0.0.1:6379>
hget

获取单个字段值

127.0.0.1:6379> hget user:1000 birthday
1995-01-01 23:11:14
hgetall

获取所有字段值,返回数组,前面是键,后面是值

127.0.0.1:6379> hgetall user:1000
username
admin
birthday
1995-01-01 23:11:14
authorized
1
127.0.0.1:6379>
hmget

返回包含多个字段值的数组,不包含键,只包含值。

127.0.0.1:6379> hmget user:1000 birthday authorized username
1995-01-01 23:11:14
1
admin
127.0.0.1:6379>
hincrby

对单个字段执行整数递增操作,字段不存在初始为0。值不是数字会报错。

127.0.0.1:6379> hincrby user:1000 age 10
10
127.0.0.1:6379> hget user:1000 age
10
127.0.0.1:6379> hincrby user:1000 birthday 10
ERR hash value is not an integer

127.0.0.1:6379>
hkeys

返回包含hash所有字段名字的数组。

127.0.0.1:6379> hkeys user:1000
username
birthday
authorized
age
127.0.0.1:6379>
hvals

返回所有字段值的数组

127.0.0.1:6379> hvals user:1000
admin
1995-01-01 23:11:14
1
10
127.0.0.1:6379>
hlen

返回hash的字段数量,若key不存在返回0

127.0.0.1:6379> hlen user:1000
4
127.0.0.1:6379>
hrangfield

随机返回hash字段

127.0.0.1:6379> hrandfield user:1000
birthday
127.0.0.1:6379> hrandfield user:1000
age
随机返回指定数量的字段

数字为正数,返回字段不重复。当数字超过字段数量时,返回所有字段。

127.0.0.1:6379> hrandfield user:1000 2
birthday
username
127.0.0.1:6379> hrandfield user:1000 2
username
age
127.0.0.1:6379> hrandfield user:1000 5
username
birthday
authorized
age
127.0.0.1:6379>

数字为负数,返回字段允许重复。

127.0.0.1:6379> hrandfield user:1000 -5
username
age
age
age
username
127.0.0.1:6379>
加上withvalues命令,字段和值一起返回
127.0.0.1:6379> hrandfield user:1000 5 withvalues
username
admin
birthday
1995-01-01 23:11:14
authorized
1
age
10
hstrlen

返回字段值的长度,若字段不存在返回0

127.0.0.1:6379> hstrlen user:1000 username
5
hsetnx

若字段不存在,就设置这个新字段。返回1表示设置了新字段,返回0表示字段存在,没有设置新字段。

127.0.0.1:6379> hsetnx user:1000 email 123456@qq.com
1
127.0.0.1:6379> hsetnx user:1000 email abcdef@qq.com
0
127.0.0.1:6379> hget user:1000 email
123456@qq.com
127.0.0.1:6379>
hexists

判断字段是否存在,返回1表示字段存在。返回0表示字段不存在。

127.0.0.1:6379> hexists user:1000 email
1
127.0.0.1:6379> hexists user:1000 email2
0
127.0.0.1:6379>
hdel

删除指定字段。若指定字段不存在则忽略。
返回成功删除字段的数量,不包括忽略的字段。

127.0.0.1:6379> hdel user:1000 email email2
1
127.0.0.1:6379> hdel user:1000 email
0
127.0.0.1:6379>

sets类型

sets是一个无序的字符串集合。

sadd

向集合中添加新元素。
若集合中元素全是整数,集合采用intset编码,集合元素按从小到大排序(默认不超过512个,可以用过set-max-intset-entries进行调整)

127.0.0.1:6379> sadd myset 5 3 1 2 4
5
127.0.0.1:6379> smembers myset
1
2
3
4
5
127.0.0.1:6379> OBJECT ENCODING myset
intset

若集合中有一个不是整数,则按hashtable编码,集合是无序的。

127.0.0.1:6379> sadd myset 5 3 1 2 4 6a
1
127.0.0.1:6379> smembers myset
6a
5
2
1
4
3
127.0.0.1:6379> OBJECT ENCODING myset
hashtable

在每次添加操作后会影响元素的排序,每次读取时顺序不变

127.0.0.1:6379> smembers myset
6a
5
2
1
4
3
127.0.0.1:6379> smembers myset
6a
5
2
1
4
3
127.0.0.1:6379> smembers myset
6a
5
2
1
4
3
127.0.0.1:6379>
smembers

查看包含所有元素的数组

127.0.0.1:6379> smembers myset
6a
5
2
1
4
3
127.0.0.1:6379>
sismember

判断sets中是否存在指定元素。存在返回1,不存在返回0

127.0.0.1:6379> sismember myset 5
1
127.0.0.1:6379> sismember myset 5a
0
127.0.0.1:6379>
使用sets来表示对象之间的关系。

新闻对象news:
id:1000,
name:作为神仙姐姐的刘亦菲,最为经典的还是这几个角色!
标签对象tags:
id:1,
name:内地明星
id:2,
name:当红女星
id:3,
name:美女图片
id:4,
name:小鲜肉
id:5,
name:穿衣搭配
新闻id1000拥有1,2,3,5标签

127.0.0.1:6379> hmset news:1000 id 1000 name "作为神仙姐姐的刘亦菲,最为经典的还是这几个角色!"
OK
127.0.0.1:6379> hmset tags:1 id 1 name 内地明星
OK
127.0.0.1:6379> hmset tags:2 id 2 name 当红女星
OK
127.0.0.1:6379> hmset tags:3 id 3 name 美女图片
OK
127.0.0.1:6379> hmset tags:4 id 4 name 小鲜肉
OK
127.0.0.1:6379> hmset tags:5 id 5 name 穿衣搭配
OK
127.0.0.1:6379> sadd news:1000:tags 1 2 3 5
4
127.0.0.1:6379> sadd tags:1:news 1000 1001
2
127.0.0.1:6379> sadd tags:2:news 1000 1003
2
127.0.0.1:6379> sadd tags:3:news 1001 1006 1007
3
127.0.0.1:6379>
sinter

取多个集合的交集,返回元素数组。
获取同时拥有标签1和标签3的文章。

127.0.0.1:6379> sinter tags:1:news tags:3:news
1001
127.0.0.1:6379>
sunion

取多个集合的并集,返回元素数组。key不存在则为空集合。
获取拥有标签1或者标签3所有文章。

127.0.0.1:6379> smembers tags:1:news
1000
1001
127.0.0.1:6379> smembers tags:3:news
1001
1006
1007
127.0.0.1:6379> sunion tags:1:news tags:3:news
1000
1001
1006
1007
127.0.0.1:6379>
sunionstore

取多个集合的并集,并存入到新的key中。若key已存在,则覆盖。
返回新key的元素数量。

127.0.0.1:6379> smembers tags:1:news
1000
1001
127.0.0.1:6379> smembers tags:3:news
1001
1006
1007
127.0.0.1:6379> sadd tags:1-3:news 999
1
127.0.0.1:6379> sunionstore tags:1-3:news tags:1:news tags:3:news
4
127.0.0.1:6379> smembers tags:1-3:news
1000
1001
1006
1007
127.0.0.1:6379>
srangmember

随机返回指定数量的元素。若未指定数量,返回单个字符串,若是二进制值,还会返回字节长度。
若数量为正数,则返回元素不重复,指定数量大于sets元素数量时返回整个sets。

127.0.0.1:6379> srandmember tags:1-3:news
1000
127.0.0.1:6379> srandmember tags:1-3:news
1006
127.0.0.1:6379> srandmember tags:1-3:news 2
1000
1001
127.0.0.1:6379> srandmember tags:1-3:news 2
1007
1001
127.0.0.1:6379> srandmember tags:1-3:news 9
1000
1001
1006
1007
127.0.0.1:6379>

若数量为负数时,返回元素可能会重复。返回元素的数量为指定的数量。

127.0.0.1:6379> srandmember tags:1-3:news -9
1007
1007
1006
1007
1007
1001
1001
1001
1007
127.0.0.1:6379>
spop

随机返回指定数量的元素,并删除这些元素。
若未指定数量,则只返回一个元素。

127.0.0.1:6379> spop tags:1-3:news 2
1001
1000
127.0.0.1:6379> smembers tags:1-3:news
1006
1007
127.0.0.1:6379> spop tags:1-3:news
1006
127.0.0.1:6379> smembers tags:1-3:news
1007
127.0.0.1:6379>
scard

返回指定sets的元素数量,若key不存在返回0

127.0.0.1:6379> scard tags:1-3:news
1
127.0.0.1:6379>
扑克牌游戏

实现一个扑克牌游戏,使用sets存放扑克牌。
clubs:梅花
diamonds:方块
hearts: 红桃/红心
spades:黑桃

127.0.0.1:6379> sadd deck C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 HJ HQ HK S1 S2 S3 S4 S5 S6  S7 S8 S9 S10 SJ SQ SK
52
127.0.0.1:6379>

复制一份牌

127.0.0.1:6379> sunionstore game:1:deck deck
52
127.0.0.1:6379>

给第一个玩家发5张牌,发了一对4

127.0.0.1:6379> spop game:1:deck 5
CJ
S10
D1
C4
D4
127.0.0.1:6379>

剩下的牌数

127.0.0.1:6379> scard game:1:deck
47
127.0.0.1:6379>

sorted sets类型

排序集合,是sets和hash的结合类型。与sets一样,集合元素不能重复。
排序集合中的每个元素都关联一个浮点数得分,就像hash一样,每个元素映射到一个值。
排序规则:

  • 如果元素A和元素B的得分不同,如果A元素的得分大于B元素的得分,那么元素A大于元素B。
  • 如果元素A和元素B的得分相同,如果A元素的字符串在字母排序上大于B字符串,那么A元素大宇B元素。集合中A和B元素字符串不能相等。
zadd

向有序集合中添加元素。每次添加一个元素时执行一个 o (log (n))操作,存入时元素已经排好序了。
zadd key [NX|XX] [GT|LT] [CH] [INCR] score member [score member…]

127.0.0.1:6379> zadd math 85.5 zhangsan 70 lisi 99 wangwu  88 zhaoliu 60 sunqi  70 zhouba
6
127.0.0.1:6379>
zrange

zrange key min max [BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
返回排序集合中指定范围类的元素。可以按索引、得分、字母顺序进行排序。
注意这里是排序后的索引。

  • 按索引范围。
    0表示排序后的第一个元素。-1表示最后一个元素,-2倒数第二个。
127.0.0.1:6379> zrange math 0 -1
sunqi
lisi
zhouba
zhangsan
zhaoliu
wangwu
127.0.0.1:6379>

添加rev命令,倒序排列

127.0.0.1:6379> zrange math 0 -1 rev withscores
wangwu
99
zhaoliu
88
zhangsan
85.5
zhouba
70
lisi
70
sunqi
60
127.0.0.1:6379>
  • 按得分范围。
    返回得分大于70小于等于90的元素。
    withscores显示得分。
    默认包括范围边界,添加(符号排除边界。
127.0.0.1:6379> zrange math (70 90 byscore withscores
zhangsan
85.5
zhaoliu
88
127.0.0.1:6379>

如果不知道得分范围,可以使用-inf和+inf包括所有得分范围。
-inf 表示负无穷
+inf表示正无穷

127.0.0.1:6379> zrange math -inf +inf byscore withscores
sunqi
60
lisi
70
zhouba
70
zhangsan
85.5
zhaoliu
88
wangwu
99
127.0.0.1:6379>

使用分页查询参数
查询分数大于70小于等于90的元素,从第二个元素开始,显示两个。

127.0.0.1:6379> zrange math (70 90 byscore withscores limit 1 2
zhaoliu
88
127.0.0.1:6379>
  • 按字母词典范围。
    所有元素的得分必须相同,如果得分不同,不会返回任何结果。字符串采用二进制字节数组进行比较。
127.0.0.1:6379> zadd zset 0 a 0 b 0 c 0 d 0 all 0 banana 0 cell 0 demo 0 effect 0 appale 0 boolean 0 custom 0 default 0 element
14
127.0.0.1:6379> zrange zset [cell (e bylex
cell
custom
d
default
demo
127.0.0.1:6379>

(表示小于边界
[表示小于等于边界

127.0.0.1:6379> zrange zset - + bylex
a
all
appale
b
banana
boolean
c
cell
custom
d
default
demo
effect
element
127.0.0.1:6379>

-表示负无穷字符串
+表示正无穷字符串

127.0.0.1:6379> zrange zset - + bylex limit 0 4
a
all
appale
b
127.0.0.1:6379>

使用limit可以实现分页的功能。

zrem

删除指定元素,返回删除成功数量。

127.0.0.1:6379> zrange math 0 -1 withscores
sunqi
60
lisi
70
zhouba
70
zhangsan
85.5
zhaoliu
88
wangwu
99
127.0.0.1:6379> zrem math zhangsan zhouba zhaoliu
3
127.0.0.1:6379> zrange math 0 -1 withscores
sunqi
60
lisi
70
wangwu
99
127.0.0.1:6379>
zrank

返回排序后元素的排名,从0开始。类似与索引。
如果key不存在或者,元素不存在,返回nil。

127.0.0.1:6379> zrange math 0 -1
sunqi
lisi
wangwu
127.0.0.1:6379> zrank key sunqi

127.0.0.1:6379> zrank math sunqi
0
127.0.0.1:6379> zrank math lisi
1
127.0.0.1:6379> zrank math wangwu
2
127.0.0.1:6379>
zscore

返回指定元素双精度浮点数的得分

127.0.0.1:6379> zscore math wangwu
99
127.0.0.1:6379>
zcard

返回排序集合元素数量

127.0.0.1:6379> zrange math 0 -1
sunqi
lisi
wangwu
127.0.0.1:6379> zcard math
3
zcount

返回指定范围内得分的元素数量。

127.0.0.1:6379> zrange math 0 -1 withscores
sunqi
60
lisi
70
wangwu
99
127.0.0.1:6379> zcount math -inf +inf
3
127.0.0.1:6379>

返回负无穷得分到正无穷得分元素数量。

127.0.0.1:6379> zcount math (60 99
2

返回得分大于60,小于等于99的元素数量

127.0.0.1:6379> zcount math -inf 80
2

返回得分大于负无穷小于等于80的元素数量。

zlexcount

所有元素得分相同,返回指定字符串字段范围内元素数量。

127.0.0.1:6379> zrange zset (c [e bylex
cell
custom
d
default
demo
127.0.0.1:6379> zlexcount zset (c [e
5
127.0.0.1:6379> zlexcount zset - [e
12
127.0.0.1:6379>
zrandmember

随机返回指定数量的元素,没有指定数量只返回一个元素。
指定数量为正数,随机返回指定数量元素,不重复,最大不超过元素总数。
指定数量为负数,随机返回指定数量元素,允许重复。

127.0.0.1:6379> zrandmember math
wangwu
127.0.0.1:6379> zrandmember math
sunqi
127.0.0.1:6379> zrandmember math 2
wangwu
lisi
127.0.0.1:6379> zrandmember math 2
sunqi
wangwu
127.0.0.1:6379> zrandmember math -2
lisi
wangwu
127.0.0.1:6379> zrandmember math -2
wangwu
lisi
127.0.0.1:6379> zrandmember math -4
sunqi
sunqi
wangwu
lisi
127.0.0.1:6379>
zpopmax

删除并返回最大得分元素,没有指定数量只删除返回一个。
指定数量最大不超过元素总数,超过总数也不会报错。

127.0.0.1:6379> zrange math 0 -1 withscores
sunqi
60
lisi
70
wangwu
99
127.0.0.1:6379> zpopmax math 2
wangwu
99
lisi
70
127.0.0.1:6379>
zpopmin

删除并返回最小得分元素,没有指定数量只删除返回一个。
指定数量最大不超过元素总数,超过总数也不会报错。

127.0.0.1:6379> zadd math 99 wangwu 70 lisi
2
127.0.0.1:6379> zpopmin math 2
sunqi
60
lisi
70
127.0.0.1:6379>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值