redis-bitmap

redis-bitmap redis位图

实现原理:

就是字符串,字符数组

优点

1.节省空间,按位存的,比如记录用户登录次数,只需要365/8≈40多byte
2.设置时候时间复杂度O(1)、读取时候时间复杂度O(n),操作是非常快的。只要长度不长,读取是很快的.

注意事项

bitmap有位数限制,512m以内,on的读取复杂度,太长效率太差了.
bitcount key 0 0 这种情况只返回前8位的统计结果.

思考

使用方法(BITPOS 2.8.7可用,代码里面有使用例子)

127.0.0.1:6379> setbit test 100 1
(integer) 0
127.0.0.1:6379> setbit test 99 1
(integer) 0
127.0.0.1:6379> setbit test 98 0
(integer) 0
127.0.0.1:6379> setbit test 97 0
(integer) 0
127.0.0.1:6379> setbit test 96 1
(integer) 0
127.0.0.1:6379> getbit test 96
(integer) 1
127.0.0.1:6379> getbit test 95
(integer) 0
127.0.0.1:6379> getbit test 97
(integer) 0
127.0.0.1:6379> getbit test 98
(integer) 0
127.0.0.1:6379> getbit test 99
(integer) 1
127.0.0.1:6379> getbit test 100
(integer) 1
127.0.0.1:6379> bitcount test 0 -1
(integer) 3

案例:

1.用户签到
用户id作为key,value为签到的情况,1代表签到,0代表未签到.

       //用户uid
        String uid = "1";
        String cacheKey = "sign_" + Integer.valueOf(uid);
        //记录有uid的key
        // $cacheKey = sprintf("sign_%d", $uid);
        
        //开始有签到功能的日期
        String startDate = "2017-01-01";

        //今天的日期
        String todayDate = "2017-01-21";
        
        //计算offset(时间搓)
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        long startTime = format.parse(startDate).getTime();
        long todayTime = format.parse(startDate).getTime();
        long offset = (long) Math.floor((todayTime - startTime) / 86400);

        System.out.println("今天是第" + offset + "天");
        //签到
        //一年一个用户会占用多少空间呢?大约365/8=45.625个字节,好小,有木有被惊呆?
        jedis.setbit(cacheKey, offset, "1");

        //查询签到情况
        boolean bitStatus = jedis.getbit(cacheKey, offset);
        //判断是否已经签到
        //计算总签到次数
        long qdCount = jedis.bitcount(cacheKey);

2.统计活跃用户数:
每天当天的日期作为key,当天的活跃用户作为offset,value设置成1,为bitcount做准备.
通过bitcount 统计value的数量,就可以知道当天活跃用户数了.
如果 是几天的活跃用户数,那么 可以用bittop 命令 合并结果.

  Map>dateActiveuser = new HashMap<>();
        Integer[] temp01 = {1,2,3,4,5,6,7,8,9,10};
        Listtemp01List = new ArrayList<>();
        Collections.addAll(temp01List,temp01);
        dateActiveuser.put("2017-01-10",temp01List);


        Integer[] temp02 = {1,2,3,4,5,6,7,8};
        Listtemp02List = new ArrayList<>();
        Collections.addAll(temp02List,temp02);
        dateActiveuser.put("2017-01-11",temp02List);

        Integer[] temp03 = {1,2,3,4,5,6};
        Listtemp03List = new ArrayList<>();
        Collections.addAll(temp03List,temp03);
        dateActiveuser.put("2017-01-12",temp03List);

        Integer[] temp04 = {1,4,5,6};
        Listtemp04List = new ArrayList<>();
        Collections.addAll(temp04List,temp04);
        dateActiveuser.put("2017-01-13",temp04List);

        Integer[] temp05 = {1,4,5,6};
        Listtemp05List = new ArrayList<>();
        Collections.addAll(temp05List,temp05);
        dateActiveuser.put("2017-01-14",temp05List);

        String date[] = {"2017-01-10","2017-01-11","2017-01-12","2017-01-13","2017-01-14"};

       //测试数据放入redis中
        for (int i=0;i

你可能感兴趣的:(redis-bitmap)