7.8 redis高级数据类型

redis高级数据类型有两个
在这里插入图片描述

独立总数:一个人一天访问一个网站多次,算一个访客(UA),即统计的时候需要去重。
占据空间虽小,但是不精确
在这里插入图片描述
适合统计用户签到,0-1问题
比如第一位的01 表示今年第一天到没到。第二位的 01 表示今年第二天到没到。第365位表示第365天到没到。这样是连续的。

这两种都适合用于对网站的运营数据进行统计。且统计的时候非常节约内存,效率高。
这两种机制 以及适用场景都不一样,本节先处理其语法问题。

在RedisTests中

演示hyperLogLog

  // 统计20万个重复数据的独立总数(独立总数即去重以后的数据个数).
    @Test
    public void testHyperLogLog() {
        String redisKey = "test:hll:01";//hll是HyperLogLog缩写

        for (int i = 1; i <= 100000; i++) {
            redisTemplate.opsForHyperLogLog().add(redisKey, i);
        }//生成十万个不重复数据

        for (int i = 1; i <= 100000; i++) {
            int r = (int) (Math.random() * 100000 + 1);//r为1-十万之间的整数
            redisTemplate.opsForHyperLogLog().add(redisKey, r);
        }//生成十万个不重复数据


        //两次生成十万个不重复数据,即生成了20万个重复数据。去重以后应该还是十万。
        long size = redisTemplate.opsForHyperLogLog().size(redisKey);
        System.out.println(size);
    }

最终结果:99553,精确值是十万,误差还算小

    // 将3组数据合并, 再统计合并后的重复数据的独立总数.
    @Test
    public void testHyperLogLogUnion() {
        String redisKey2 = "test:hll:02";
        for (int i = 1; i <= 10000; i++) {
            redisTemplate.opsForHyperLogLog().add(redisKey2, i);
        }

        String redisKey3 = "test:hll:03";
        for (int i = 5001; i <= 15000; i++) {//和redisKey2中的数据有一定交叉
            redisTemplate.opsForHyperLogLog().add(redisKey3, i);
        }

        String redisKey4 = "test:hll:04";
        for (int i = 10001; i <= 20000; i++) {//和redisKey3 中的数据有一定交叉
            redisTemplate.opsForHyperLogLog().add(redisKey4, i);
        }
//总共三万条,去重以后只有两万条
        
        String unionKey = "test:hll:union";
        redisTemplate.opsForHyperLogLog().union(unionKey, redisKey2, redisKey3, redisKey4);

        long size = redisTemplate.opsForHyperLogLog().size(unionKey);
        System.out.println(size);
    }

结果:19833,准确值是2w

演示BitMap
// 统计一组数据的布尔值

@Test
public void testBitMap() {
    String redisKey = "test:bm:01";

    // 记录
    redisTemplate.opsForValue().setBit(redisKey, 1, true);//setBit表示按位存数据的方法1第一位为true
    redisTemplate.opsForValue().setBit(redisKey, 4, true);//第4位为true
    redisTemplate.opsForValue().setBit(redisKey, 7, true);//其余位置默认为0

    // 查询
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 0));//false
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 1));//true
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 2));//false

    // 统计true的个数
    Object obj = redisTemplate.execute(new RedisCallback() {
        @Override
        public Object doInRedis(RedisConnection connection) throws DataAccessException {
            return connection.bitCount(redisKey.getBytes());
        }
    });

    System.out.println(obj);
}

最终结果:
在这里插入图片描述
测试2

// 统计3组数据的布尔值, 并对这3组数据做OR运算.
@Test
public void testBitMapOperation() {
    String redisKey2 = "test:bm:02";
    redisTemplate.opsForValue().setBit(redisKey2, 0, true);
    redisTemplate.opsForValue().setBit(redisKey2, 1, true);
    redisTemplate.opsForValue().setBit(redisKey2, 2, true);

    String redisKey3 = "test:bm:03";
    redisTemplate.opsForValue().setBit(redisKey3, 2, true);
    redisTemplate.opsForValue().setBit(redisKey3, 3, true);
    redisTemplate.opsForValue().setBit(redisKey3, 4, true);

    String redisKey4 = "test:bm:04";
    redisTemplate.opsForValue().setBit(redisKey4, 4, true);
    redisTemplate.opsForValue().setBit(redisKey4, 5, true);
    redisTemplate.opsForValue().setBit(redisKey4, 6, true);

    String redisKey = "test:bm:or";
    Object obj = redisTemplate.execute(new RedisCallback() {
        @Override
        public Object doInRedis(RedisConnection connection) throws DataAccessException {
            connection.bitOp(RedisStringCommands.BitOperation.OR,
                    redisKey.getBytes(), redisKey2.getBytes(), redisKey3.getBytes(), redisKey4.getBytes());//redisKey.getBytes()表示运算结果。redisKey2.getBytes(), redisKey3.getBytes(), redisKey4.getBytes()是研做运算的数据
            return connection.bitCount(redisKey.getBytes());
        }
    });

    System.out.println(obj);

    //打印redisKey中的每一个值
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 0));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 1));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 2));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 3));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 4));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 5));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 6));
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值