Redis 数据类型list、hash、zset 原理、使用场景说明

面试中常会被问到Redis 的数据类型用过哪些,被问的多了就想整理一下,以被下次再被问时可以很好的回复,现在对redis中list、hash、zset进行梳理。

一、list

Redis list的实现为一个双向链表 ; List 列表是简单的字符串列表,按照插入顺序排序,可以从头部或尾部向 List 列表添加元素。

1.1说明:
1、 Redis的列表允许用户从序列的两端推入或者弹出元素
2、可以做消息队列,以完成多程序之间的消息交换。可以用push操作将任务存在list中(生产者), 然后线程在用pop操作将任务取出进行执行。(消费者)

1.2 使用场景:
  需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序
  list类型:保存多个数据,底层使用双向链表存储结构实现

ps: lpop、rpop 会将list元素取出并移出,和队列特性一样;
  lrange、rrange 取出元素但不移除

1.3 可实现常用数据结构
  Stack(栈) = LPUSH + LPOP
  Queue(队列)= LPUSH + RPOP
  Blocking MQ(阻塞队列)= LPUSH + BRPOP
1.4常用命令:
  lpush,rpush,lpop,rpop,lrange,BLPOP(阻塞版)等。

1.5代码实例

 /**
     * redis 数据类型list测试
     * Redis list的实现为一个双向链表
     * List 列表是简单的字符串列表,按照插入顺序排序,可以从头部或尾部向 List 列表添加元素。
     * 使用场景
     * list类型:保存多个数据,底层使用双向链表存储结构实现
     * <p>
     * ps: lpop、rpop 会将list元素取出并移出,和队列特性一样;
     * lrange、rrange 取出元素但不移除
     */
    @Test
    public void redisList() {
        //1.连接redis
        Jedis jedis = new Jedis("127.0.0.1", 6379);

        //2.操作redis
        jedis.lpush("list1", "a", "b", "c");
        jedis.rpush("list1", "x");
        // 取出所有数据  不会将元素移除
        List<String> list1 = jedis.lrange("list1", 0, -1);
        System.out.println("list1 = " + list1);
        // 可以从两边取数据插入,也可以从左右两边取数据--Redis的列表允许用户从序列的两端推入或者弹出元素
        System.out.println("jedis.lpop(\"list1\") = " + jedis.lpop("list1"));
        System.out.println("jedis.rpop(\"list1\") = " + jedis.rpop("list1"));
        List<String> list2 = jedis.lrange("list1", 0, -1);
        list2.forEach(x -> {
            System.out.println("jedis.lpop(\"list2\") = " + jedis.lpop("list1"));
        });
        //(2)消息队列,以完成多程序之间的消息交换。可以用push操作将任务存在list中(生产者),然后线程在用pop操作将任务取出进行执行。(消费者)
        // blpop 阻塞弹出
//      jedis.blpop("list1");

        jedis.close();

    }

二、 hash 类型 

 
2.1 说明:hash 存储可以存储一个对象-多个属性,取时直接取出成 转换成一个Map,
省去了像存放json字符串序列化和反序列化也便于修改
新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息
需要的存储结构:一个存储空间保存多个键值对数据
ps: hash类型:底层使用哈希表结构实现数据存储
hash类型下的value只能存储字符串
2.2常用命令
hset、hget、hgetall、hkeys、hvals、hsetnx
hmget key field1,feild2 :可以获取多个filed

2.3 代码实例

/**
     * redis 数据类型hash测试
     * 说明:hash 存储可以存储一个对象-多个属性,取时直接取出成 转换成一个Map,
     *  省去了像存放json字符串序列化和反序列化也便于修改
     *  新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息    
     * 常用命令
     * hset、hget、hgetall、hkeys、hvals、hsetnx
     * hmget key field1,feild2 :可以获取多个filed
     */
    @Test
    public void redisHash() {

        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.set("liyanbo", "777");
        System.out.println("jedis.get(\"liyanbo\") = " + jedis.get("liyanbo"));

        //1、 hash 存储可以存储一个对象-多个属性,取时直接取出成 转换成一个Map,省去了像存放json字符串序列化和反序列化也便于修改
        jedis.hset("hashKey", "keyO1", "key1");
        jedis.hset("hashKey", "keyO2", "key2");
        jedis.hset("hashKey", "keyO3", "key3");
        Map<String, String> map02 = jedis.hgetAll("hashKey");
        System.out.println("map02 = " + map02);// 可以直接使用 map 取对应的值

        //1.3
        jedis.close();
    }

3、zSet 数据类型

zSetdiceng底层数据结构是跳跃表(skipList),因为skiplist算法实现的难度要低于平衡树

3.1 说明:Redis zset和set一样也是string类型元素的集合,且不允许重复的成员。不同之处在于,
  每个元素都与双类型的分数相关联
  Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
  不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
  有序集合的成员是唯一的,但分数(score)却可以重复
3.2 场景:

  1、实现积分排行榜功能,就采用了redis zset有序集合来实现

  2、学生ID,学生分数,存放后可排序
  Redis zset和set一样也是string类型元素的集合,且不允许重复的成员。不同之处在于,每个元素都与双类型的分数相关联

3.3常用命令:

  zadd:新增成员, zadd:新增成员
  zrangebylex:指定集合区间,获取列表
  zrangebyscore:指定分数区间,获取列表
  zrevrange:倒序展示列表

3.4 代码实例

/**
     * redis 数据类型ZSet测试
     * 说明:Redis zset和set一样也是string类型元素的集合,且不允许重复的成员。不同之处在于,
     *  每个元素都与双类型的分数相关联
     *  Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
     *  不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
     *  有序集合的成员是唯一的,但分数(score)却可以重复
     * 场景:
     * 1、实现积分排行榜功能,就采用了redis zset有序集合来实现
     * 2、学生ID,学生分数,存放后可排序
     *  Redis zset和set一样也是string类型元素的集合,且不允许重复的成员。不同之处在于,每个元素都与双类型的分数相关联
     */
    @Test
    public void redisZSet() {

        //1.连接redis
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.zadd("zSetKey", 10, "liyanbo");
        jedis.zadd("zSetKey", 9, "yanda");
        jedis.zadd("zSetKey", 15, "zhiyuan");
        jedis.zadd("zSetKey", 12, "chengqiang");
        // 从高到底排序输出指定范围的数据
        Set<String> setSort = jedis.zrevrange("zSetKey", 0, 4);
        System.out.println("setSort = " + setSort);

        // 取出最高分数信息
//        System.out.println("jedis.zpopmax(\"zSetKey\") = " + jedis.zpopmin("zSetKey"));

        jedis.close();
    }

看到的小伙伴如有疑问或问题可以评论回复一起讨论沟通。

 

posted @ 2022-11-25 16:10  xiaoBai1001  阅读(882)  评论(0编辑  收藏  举报