redis in action 读书记录01 redis的一些常用命令

Redis in action 读书记录01 redis的一些常用命令

Redis 数据结构

  • String: 字符串
  • Hash: 散列
  • List: 列表
  • Set: 集合
  • Sorted Set: 有序集合

Redis常用命令

string字符串常用命令
字符串get、set、del命令
命令行为
GET获取存储在给定键中的值
SET设置存储在给定键中的值
DEL删除存储在给定键中的值
字符串中的自增命令和自减命令
命令行为
INCRINCR key-name 将键存储的值加上1
DECRDECR key-name 将键存储的值减去1
INCRBYINCRBY key-name amount 将键存储的值加上整数amount
DECRBYDECRBY key-name amount 将键存储的值减去整数amount
INCRBYFLOATINCRBYFLOAT key-name amount 将键存储的值加上浮点数amount

当用户将一个值存储到 Redis 字符串里面的时候,如果这个值可以被解释(interpret)为十 进制整数或者浮点数,那么 Redis 会察觉到这一点,并允许用户对这个字符串执行各种 INCR和DECR操作。如果用户对一个不存在的键或者一个保存了空串的键执行自增或者自减操作,那么Redis 在执行操作时会将这个键的值当作是 0 来处理。如果用户尝试对一个值无法被解释为整数或者浮点数的字符串键执行自增或者自减操作,那么 Redis 将向用户返回一个错误。代码清单 3-1展示了对字符串执行自增操作和自减操作的一些例子。

字符串处理子串和二进制位的命令
命令用例和描述
APPENDAPPEND key-name value 将值value追加到给定键key-name当前存储的值的末尾
GETRANGEGETRANGE key-name start end 获取一个由偏移量start至偏移量end范围内所有字符组成的子串,包括start和end在内
SETRANGESETRANGE key-name offset value—将从 start 偏移量开始的子串设置为给定值
GETBITGETBIT key-name offset—将字节串看作是二进制位串(bit string),并返回位串中偏移量为offset 的二进制位的值
SETBITSETBIT key-name offset value—将字节串看作是二进制位串,并将位串中偏移量为 offset的二进制位的值
BITCOUNTBITCOUNT key-name [start end]—统计二进制位串里面值为 1 的二进制位的数量,如果给定了可选的 start 偏移量和 end 偏移量,那么只对偏移量指定范围内的二进制位进行统计
BITOPBITOP operation dest-key key-name [key-name …]—对一个或多个二进制位串执行包括并(AND)、或 (OR)、异或(XOR)、非 (NOT)在内的任意一种按位运算操作(bitwise operation),

在这里插入图片描述

在这里插入图片描述

list列表常用命令
命令行为
RPUSHRPUSH key-name value [value …]—将一个或多个值推入列表的右端
LRANGELPUSH key-name value [value …]—将一个或多个值推入列表的左端
LINDEXLINDEX key-name offset—返回列表中偏移量为 offset 的元素
LPOPLPOP key-name—移除并返回列表最左端的元素
RPOPRPOP key-name—移除并返回列表最右端的元素
LRANGELRANGE key-name start end—返回列表从 start 偏移量到 end 偏移量范围内的所有元素,其中偏移量为 start 和偏移量为 end 的元素也会包含在被返回的元素之内
LTRIMLTRIM key-name start end—对列表进行修剪,只保留从 start 偏移量到 end 偏移量范围内的元素,其中偏移量为 start 和偏移量为 end 的元素也会被保留
BLPOPBLPOP key-name [key-name …] timeout—从第一个非空列表中弹出位于最左端的元素,或者在 timeout 秒之内阻塞并等待可弹出的元素出现
BRPOPBRPOP key-name [key-name …] timeout—从第一个非空列表中弹出位于最右端的元素,或者在 timeout 秒之内阻塞并等待可弹出的元素出现
RPOPLPUSHRPOPLPUSH source-key dest-key—从 source-key 列表中弹出位于最右端的元素,然后将这个元素推入 dest-key 列表的最左端,并向用户返回这个元素
BRPOPLPUSHBRPOPLPUSH source-key dest-key timeout—从 source-key 列表中弹出位于最右端的元素,然后将这个元素推入 dest-key 列表的最左端,并向用户返回这个元素;如果 source-key为空,那么在 timeout 秒之内阻塞并等待可弹出的元素出现

在这里插入图片描述

在这里插入图片描述

set集合常用命令
命令行为
SADDSADD key-name item [item …]—将一个或多个元素添加到集合里面,并返回被添加元素当中原本并不存在于集合里面的元素数量
SMEMBERSSISMEMBER key-name item—返回集合包含的所有元素
SISMEMBERSMEMBERS key-name—检查给定元素是否存在于集合中
SREMSREM key-name item [item …]—从集合里面移除一个或多个元素,并返回被移除元素的数量
SCARDSCARD key-name—返回集合包含的元素的数量
SRANDMEMBERSRANDMEMBER key-name [count]—从集合里面随机地返回一个或多个元素。当 count为正数时,命令返回的随机元素不会重复;当 count 为负数时,命令返回的随机元素可能会出现重复
SPOPSPOP key-name—随机地移除集合中的一个元素,并返回被移除的元素
SMOVESMOVE source-key dest-key item—如果集合 source-key 包含元素 item,那么从集合 source-key 里面移除元素 item,并将元素 item 添加到集合 dest-key 中;如果 item被成功移除,那么命令返回 1,否则返回 0
SDIFFSDIFF key-name [key-name …]—返回那些存在于第一个集合、但不存在于其他集合中的元素(数学上的差集运算)
SDIFFSTORESDIFFSTORE dest-key key-name [key-name …]—将那些存在于第一个集合但并不存在于其他集合中的元素(数学上的差集运算)存储到 dest-key 键里面
SINTERSINTER key-name [key-name …]—返回那些同时存在于所有集合中的元素(数学上的交集运算)
SINTERSTORESINTERSTORE dest-key key-name [key-name …]—将那些同时存在于所有集合的元素(数学上的交集运算)存储到 dest-key 键里面
SUNIONSUNION key-name [key-name …]—返回那些至少存在于一个集合中的元素(数学上的并集计算)
SUNIONSTORESUNIONSTORE dest-key key-name [key-name …]—将那些至少存在于一个集合中的元素(数学上的并集计算)存储到 dest-key 键里面

在这里插入图片描述

在这里插入图片描述

hash散列常用命令
命令行为
HSET在散列里面关联起给定的键值对
HGET获取指定散列键的值
HGETALL获取散列包含的所有键值对
HDELHDEL key-name key [key …]—删除散列里面的一个或多个键值对,返回成功找到并删除的键值对数量
HLENHLEN key-name—返回散列包含的键值对数量
HMGETHMGET key-name key [key …]—从散列里面获取一个或多个键的值
HMSETHMSET key-name key value [key value …]—为散列里面的一个或多个键设置值
HEXISTSHEXISTS key-name key—检查给定键是否存在于散列中
HKEYSHKEYS key-name—获取散列包含的所有键
HVALSHVALS key-name—获取散列包含的所有值
HGETALLHGETALL key-name—获取散列包含的所有键值对
HINCRBYHINCRBY key-name increment—将键key存储的值加上整数increment
HINCRBYFLOATHINCRBYFLOAT key-name key increment—将键key存储的值加上浮点数increment

尽管有 HGETALL 存在,但 HKEYS 和 HVALS 也是非常有用的:如果散列包含的值非常大,那么用户可以先使用 HKEYS 取出散列包含的所有键,然后再使用 HGET 一个接一个地取出键的值,从而避免因为一次获取多个大体积的值而导致服务器阻塞。

在这里插入图片描述

在这里插入图片描述

zset有序集合常用命令
命令行为
ZADDZADD key-name score member [score member …]—将带有给定分值的成员添加到有序
ZRANGEZRANGE key-name start stop [WITHSCORES]—返回有序集合中排名介于 start 和 stop之间的成员,如果给定了可选的 WITHSCORES 选项,那么命令会将成员的分值也一并返回
ZRANGEBYSCORE获取有序集合在给定分值范围内的所有元素
ZREMZREM key-name member [member …]—从有序集合里面移除给定的成员,并返回被移除成员的数量
ZCARDZCARD key-name—返回有序集合包含的成员数量
ZINCRBYZINCRBY key-name increment member—将 member 成员的分值加上 increment
ZCOUNTZCOUNT key-name min max—返回分值介于 min 和 max 之间的成员数量
ZRANKZRANK key-name member—返回成员 member 在有序集合中的排名
ZSCOREZSCORE key-name member—返回成员 member 的分值
ZREVRANKZREVRANK key-name member—返回有序集合里成员 member 的排名,成员按照分值从大到小排列
ZREVRANGEZREVRANGE key-name start stop [WITHSCORES]—返回有序集合给定排名范围内的成员,成员按照分值从大到小排列
ZRANGEBYSCOREZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]—返回有序集合中,分值介于 min 和 max 之间的所有成员
ZREVRANGEBYSCOREZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]—获取有序集合中分值介于 min 和 max 之间的所有成员,并按照分值从大到小的顺序来返回它们
ZREMRANGEBYRANKZREMRANGEBYRANK key-name start stop—移除有序集合中排名介于start和stop之间的所有成员
ZREMRANGEBYSCOREZREMRANGEBYSCORE key-name min max—移除有序集合中分值介于 min 和 max 之间的所有成员
ZINTERSTOREZINTERSTORE dest-key key-count key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]—对给定的有序集合执行类似于集合的交集运算
ZUNIONSTOREZUNIONSTORE dest-key key-count key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]—对给定的有序集合执行类似于集合的并集运算

在这里插入图片描述

在这里插入图片描述

Chapter01.java

import redis.clients.jedis.Jedis;
import redis.clients.jedis.ZParams;

import java.util.*;

/**
 * @author DZHooo
 * @version 1.0
 * @date 2021/11/21 22:53
 * @description: TODO
 */

public class Chapter01 {

    /**
     * 一个有序集合 key:文章ID , value:文章发布时间
     * 一个有序集合 key:文章ID , value:文章的评分
     * 集合 key:文章ID , value:已投票用户ID
     * 散列 key:文章ID , value: (title: value, link: value,...)
     *
     */

    private static final int ONE_WEEK_IN_SECONDS = 7 * 86400;   //七天的秒数

    private  static final int VOTE_SCORE = 432;    //   86400 / 200 = 432 书中200票的原因

    private static final int ARTICLES_PER_PAGE = 25;

    public static void main(String[] args) {
        new Chapter01().run();
    }

    public void run() {
        Jedis conn = new Jedis("localhost");
        conn.select(15);

        String articleId = postArticle(
                conn, "username", "A title", "http://www.google.com");
        System.out.println("We posted a new article with id: " + articleId);
        System.out.println("Its HASH looks like:");
        Map<String,String> articleData = conn.hgetAll("article:" + articleId);
        for (Map.Entry<String,String> entry : articleData.entrySet()){
            System.out.println("  " + entry.getKey() + ": " + entry.getValue());
        }

        System.out.println();

        articleVote(conn, "other_user", "article:" + articleId);
        String votes = conn.hget("article:" + articleId, "votes");
        System.out.println("We voted for the article, it now has votes: " + votes);
        assert Integer.parseInt(votes) > 1;

        System.out.println("The currently highest-scoring articles are:");
        List<Map<String,String>> articles = getArticles(conn, 1);
        printArticles(articles);
        assert articles.size() >= 1;

        addGroups(conn, articleId, new String[]{"new-group"});
        System.out.println("We added the article to a new group, other articles include:");
        articles = getGroupArticles(conn, "new-group", 1);
        printArticles(articles);
        assert articles.size() >= 1;
    }

    //调用这个函数进行投票,投票限制日期,只能投一次
    public void articleVote(Jedis conn,String user,String article) {
        //用UTC时区1970年1月1日到现在为止经过的秒数 减去 七天的秒数
        long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
        //这个有序集合的成员为文章ID,分值为文章的发布时间  获取这个文章发布的时间秒数 如果大于cutoff,说明文章发布超过七天
        if(conn.zscore("time:",article) < cutoff) {
            return;
        }
        //获取字符串article中的文章ID,在':'之后
        String articleId = article.substring(article.indexOf(':') + 1);
        //投票在集合中报存,键名为voted:[文章ID],值为用户名,用集合存可以让一个用户只能投同一个文章一次票
        if(conn.sadd("voted:" + articleId, user) == 1) {
            //在第二个有序集合中,分值为文章的评分,投一票让该文章评分自增
            conn.zincrby("score:",VOTE_SCORE,article);
            //投票数量自增   散列用来存文章内容,键名为文章ID,值为文章内容对应的键值
            conn.hincrBy(article,"votes",1);
        }
    }

    //发布文章
    public String postArticle(Jedis conn, String user, String title, String link) {
        //文章ID自增+1
        String articleId = String.valueOf(conn.incr("article:"));

        String voted = "voted:" + articleId;
        //为这篇文章新增一个键名为voted:文章ID的集合,先为集合加一个成员user
        conn.sadd(voted, user);
        //设置过期时间七天
        conn.expire(voted, ONE_WEEK_IN_SECONDS);

        long now = System.currentTimeMillis() / 1000;
        //文章ID
        String article = "article:" + articleId;
        //散列的值
        HashMap<String,String> articleData = new HashMap<>();
        articleData.put("title", title);
        articleData.put("link", link);
        articleData.put("user", user);
        articleData.put("now", String.valueOf(now));
        articleData.put("votes", "1");
        //文章数据 键为文章ID,值为文章数据
        conn.hmset(article,articleData);
        //评分有序集合
        conn.zadd("score:",now + VOTE_SCORE,article);
        //时间有序集合
        conn.zadd("time:",now,article);

        return articleId;
    }

    //这个只用与提取评分的有序集合
    public List<Map<String, String>> getArticles(Jedis conn, int page) {
        return getArticles(conn,page,"score:");
    }

    //这个可以通过order取发布时间或评分的有序集合  参数order也是有序集合的键名
    public List<Map<String, String>> getArticles(Jedis conn, int page, String order) {

        int start = (page - 1) * ARTICLES_PER_PAGE;
        int end = start + ARTICLES_PER_PAGE - 1;

        Set<String> ids = conn.zrevrange(order, start, end);
        List<Map<String,String>> articles = new ArrayList<>();
        for(String id : ids) {
            Map<String,String> articleData = conn.hgetAll(id);
            articleData.put("id", id);
            articles.add(articleData);
        }

        return articles;
    }


    public void addGroups(Jedis conn, String articleId, String[] toAdd) {
        String article = "article:" + articleId;
        for(String group : toAdd) {
            conn.sadd("group:" + group, article);
        }
    }


    //程序可以得到按照文章评分排序的群组文章
    public List<Map<String,String>> getGroupArticles(Jedis conn, String group, int page) {
        return getGroupArticles(conn, group, page,"score:");
    }


    public List<Map<String,String>> getGroupArticles(Jedis conn, String group, int page, String order) {
        String key = order + group;
        if(!conn.exists(key)) {
            ZParams params = new ZParams().aggregate(ZParams.Aggregate.MAX);
            conn.zinterstore(key, params, "group:" + group, order);
            conn.expire(key, 60);
        }
        return getArticles(conn, page, key);
    }

    private void printArticles(List<Map<String,String>> articles){
        for (Map<String,String> article : articles){
            System.out.println("  id: " + article.get("id"));
            for (Map.Entry<String,String> entry : article.entrySet()){
                if (entry.getKey().equals("id")){
                    continue;
                }
                System.out.println("    " + entry.getKey() + ": " + entry.getValue());
            }
        }
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值