Redis in action 读书记录01 redis的一些常用命令
Redis 数据结构
- String: 字符串
- Hash: 散列
- List: 列表
- Set: 集合
- Sorted Set: 有序集合
Redis常用命令
string字符串常用命令
字符串get、set、del命令
命令 | 行为 |
---|
GET | 获取存储在给定键中的值 | SET | 设置存储在给定键中的值 | DEL | 删除存储在给定键中的值 |
字符串中的自增命令和自减命令
命令 | 行为 |
---|
INCR | INCR key-name 将键存储的值加上1 | DECR | DECR key-name 将键存储的值减去1 | INCRBY | INCRBY key-name amount 将键存储的值加上整数amount | DECRBY | DECRBY key-name amount 将键存储的值减去整数amount | INCRBYFLOAT | INCRBYFLOAT key-name amount 将键存储的值加上浮点数amount |
当用户将一个值存储到 Redis 字符串里面的时候,如果这个值可以被解释(interpret)为十 进制整数或者浮点数,那么 Redis 会察觉到这一点,并允许用户对这个字符串执行各种 INCR和DECR操作。如果用户对一个不存在的键或者一个保存了空串的键执行自增或者自减操作,那么Redis 在执行操作时会将这个键的值当作是 0 来处理。如果用户尝试对一个值无法被解释为整数或者浮点数的字符串键执行自增或者自减操作,那么 Redis 将向用户返回一个错误。代码清单 3-1展示了对字符串执行自增操作和自减操作的一些例子。
字符串处理子串和二进制位的命令
命令 | 用例和描述 |
---|
APPEND | APPEND key-name value 将值value追加到给定键key-name当前存储的值的末尾 | GETRANGE | GETRANGE key-name start end 获取一个由偏移量start至偏移量end范围内所有字符组成的子串,包括start和end在内 | SETRANGE | SETRANGE key-name offset value—将从 start 偏移量开始的子串设置为给定值 | GETBIT | GETBIT key-name offset—将字节串看作是二进制位串(bit string),并返回位串中偏移量为offset 的二进制位的值 | SETBIT | SETBIT key-name offset value—将字节串看作是二进制位串,并将位串中偏移量为 offset的二进制位的值 | BITCOUNT | BITCOUNT key-name [start end]—统计二进制位串里面值为 1 的二进制位的数量,如果给定了可选的 start 偏移量和 end 偏移量,那么只对偏移量指定范围内的二进制位进行统计 | BITOP | BITOP operation dest-key key-name [key-name …]—对一个或多个二进制位串执行包括并(AND)、或 (OR)、异或(XOR)、非 (NOT)在内的任意一种按位运算操作(bitwise operation), |
list列表常用命令
命令 | 行为 |
---|
RPUSH | RPUSH key-name value [value …]—将一个或多个值推入列表的右端 | LRANGE | LPUSH key-name value [value …]—将一个或多个值推入列表的左端 | LINDEX | LINDEX key-name offset—返回列表中偏移量为 offset 的元素 | LPOP | LPOP key-name—移除并返回列表最左端的元素 | RPOP | RPOP key-name—移除并返回列表最右端的元素 | LRANGE | LRANGE key-name start end—返回列表从 start 偏移量到 end 偏移量范围内的所有元素,其中偏移量为 start 和偏移量为 end 的元素也会包含在被返回的元素之内 | LTRIM | LTRIM key-name start end—对列表进行修剪,只保留从 start 偏移量到 end 偏移量范围内的元素,其中偏移量为 start 和偏移量为 end 的元素也会被保留 | BLPOP | BLPOP key-name [key-name …] timeout—从第一个非空列表中弹出位于最左端的元素,或者在 timeout 秒之内阻塞并等待可弹出的元素出现 | BRPOP | BRPOP key-name [key-name …] timeout—从第一个非空列表中弹出位于最右端的元素,或者在 timeout 秒之内阻塞并等待可弹出的元素出现 | RPOPLPUSH | RPOPLPUSH source-key dest-key—从 source-key 列表中弹出位于最右端的元素,然后将这个元素推入 dest-key 列表的最左端,并向用户返回这个元素 | BRPOPLPUSH | BRPOPLPUSH source-key dest-key timeout—从 source-key 列表中弹出位于最右端的元素,然后将这个元素推入 dest-key 列表的最左端,并向用户返回这个元素;如果 source-key为空,那么在 timeout 秒之内阻塞并等待可弹出的元素出现 |
set集合常用命令
命令 | 行为 |
---|
SADD | SADD key-name item [item …]—将一个或多个元素添加到集合里面,并返回被添加元素当中原本并不存在于集合里面的元素数量 | SMEMBERS | SISMEMBER key-name item—返回集合包含的所有元素 | SISMEMBER | SMEMBERS key-name—检查给定元素是否存在于集合中 | SREM | SREM key-name item [item …]—从集合里面移除一个或多个元素,并返回被移除元素的数量 | SCARD | SCARD key-name—返回集合包含的元素的数量 | SRANDMEMBER | SRANDMEMBER key-name [count]—从集合里面随机地返回一个或多个元素。当 count为正数时,命令返回的随机元素不会重复;当 count 为负数时,命令返回的随机元素可能会出现重复 | SPOP | SPOP key-name—随机地移除集合中的一个元素,并返回被移除的元素 | SMOVE | SMOVE source-key dest-key item—如果集合 source-key 包含元素 item,那么从集合 source-key 里面移除元素 item,并将元素 item 添加到集合 dest-key 中;如果 item被成功移除,那么命令返回 1,否则返回 0 | SDIFF | SDIFF key-name [key-name …]—返回那些存在于第一个集合、但不存在于其他集合中的元素(数学上的差集运算) | SDIFFSTORE | SDIFFSTORE dest-key key-name [key-name …]—将那些存在于第一个集合但并不存在于其他集合中的元素(数学上的差集运算)存储到 dest-key 键里面 | SINTER | SINTER key-name [key-name …]—返回那些同时存在于所有集合中的元素(数学上的交集运算) | SINTERSTORE | SINTERSTORE dest-key key-name [key-name …]—将那些同时存在于所有集合的元素(数学上的交集运算)存储到 dest-key 键里面 | SUNION | SUNION key-name [key-name …]—返回那些至少存在于一个集合中的元素(数学上的并集计算) | SUNIONSTORE | SUNIONSTORE dest-key key-name [key-name …]—将那些至少存在于一个集合中的元素(数学上的并集计算)存储到 dest-key 键里面 |
hash散列常用命令
命令 | 行为 |
---|
HSET | 在散列里面关联起给定的键值对 | HGET | 获取指定散列键的值 | HGETALL | 获取散列包含的所有键值对 | HDEL | HDEL key-name key [key …]—删除散列里面的一个或多个键值对,返回成功找到并删除的键值对数量 | HLEN | HLEN key-name—返回散列包含的键值对数量 | HMGET | HMGET key-name key [key …]—从散列里面获取一个或多个键的值 | HMSET | HMSET key-name key value [key value …]—为散列里面的一个或多个键设置值 | HEXISTS | HEXISTS key-name key—检查给定键是否存在于散列中 | HKEYS | HKEYS key-name—获取散列包含的所有键 | HVALS | HVALS key-name—获取散列包含的所有值 | HGETALL | HGETALL key-name—获取散列包含的所有键值对 | HINCRBY | HINCRBY key-name increment—将键key存储的值加上整数increment | HINCRBYFLOAT | HINCRBYFLOAT key-name key increment—将键key存储的值加上浮点数increment |
尽管有 HGETALL 存在,但 HKEYS 和 HVALS 也是非常有用的:如果散列包含的值非常大,那么用户可以先使用 HKEYS 取出散列包含的所有键,然后再使用 HGET 一个接一个地取出键的值,从而避免因为一次获取多个大体积的值而导致服务器阻塞。
zset有序集合常用命令
命令 | 行为 |
---|
ZADD | ZADD key-name score member [score member …]—将带有给定分值的成员添加到有序 | ZRANGE | ZRANGE key-name start stop [WITHSCORES]—返回有序集合中排名介于 start 和 stop之间的成员,如果给定了可选的 WITHSCORES 选项,那么命令会将成员的分值也一并返回 | ZRANGEBYSCORE | 获取有序集合在给定分值范围内的所有元素 | ZREM | ZREM key-name member [member …]—从有序集合里面移除给定的成员,并返回被移除成员的数量 | ZCARD | ZCARD key-name—返回有序集合包含的成员数量 | ZINCRBY | ZINCRBY key-name increment member—将 member 成员的分值加上 increment | ZCOUNT | ZCOUNT key-name min max—返回分值介于 min 和 max 之间的成员数量 | ZRANK | ZRANK key-name member—返回成员 member 在有序集合中的排名 | ZSCORE | ZSCORE key-name member—返回成员 member 的分值 | ZREVRANK | ZREVRANK key-name member—返回有序集合里成员 member 的排名,成员按照分值从大到小排列 | ZREVRANGE | ZREVRANGE key-name start stop [WITHSCORES]—返回有序集合给定排名范围内的成员,成员按照分值从大到小排列 | ZRANGEBYSCORE | ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]—返回有序集合中,分值介于 min 和 max 之间的所有成员 | ZREVRANGEBYSCORE | ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]—获取有序集合中分值介于 min 和 max 之间的所有成员,并按照分值从大到小的顺序来返回它们 | ZREMRANGEBYRANK | ZREMRANGEBYRANK key-name start stop—移除有序集合中排名介于start和stop之间的所有成员 | ZREMRANGEBYSCORE | ZREMRANGEBYSCORE key-name min max—移除有序集合中分值介于 min 和 max 之间的所有成员 | ZINTERSTORE | ZINTERSTORE dest-key key-count key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]—对给定的有序集合执行类似于集合的交集运算 | ZUNIONSTORE | ZUNIONSTORE 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.*;
public class Chapter01 {
private static final int ONE_WEEK_IN_SECONDS = 7 * 86400;
private static final int VOTE_SCORE = 432;
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) {
long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
if(conn.zscore("time:",article) < cutoff) {
return;
}
String articleId = article.substring(article.indexOf(':') + 1);
if(conn.sadd("voted:" + articleId, user) == 1) {
conn.zincrby("score:",VOTE_SCORE,article);
conn.hincrBy(article,"votes",1);
}
}
public String postArticle(Jedis conn, String user, String title, String link) {
String articleId = String.valueOf(conn.incr("article:"));
String voted = "voted:" + articleId;
conn.sadd(voted, user);
conn.expire(voted, ONE_WEEK_IN_SECONDS);
long now = System.currentTimeMillis() / 1000;
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");
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:");
}
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());
}
}
}
}
|