Redis 数据结结构(一)—字符串、哈希表、列表
Redis(版本7.0)的数据结构主要包括字符串(String)、哈希表(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)、超日志(HyperLogLog)、位图(Bitmap)、地理坐标(Geo)、流(Stream)。
1 字符串 String
键和值既可以是文字也可以是二进制数据。
赋值与读取 | 单个:GET、SET、GETSET(获取旧值并用新值替换) 批量操作:MGET、MSET、MSTNX |
字符串 | 字符串的字节长度:STRLEN 获取字符串指定索引范围上的内容:GETRANGE 对字符串的指定索引范围进行设置:SETRANGE 追加新内容到值的末尾:APPEND |
数值运算 | 整数运算(不可用于浮点数运算):INCRBY、INCR、DECRBY、DECR 浮点数(可用于整数运算):INCRBYFLOAT |
表 字符串数据结构相关命令
NX (Non-Existing):字段不存在则赋值,否则不操作。
XX(Existing):字段存在则赋值,否则不操作。
图 字符串的索引
1.1 示例
限速器:为了保障系统的安全性和性能,并保证系统的重要资源不会滥用。系统的会对用户的行为做些限制: 例如,在一定时间内,用户只能对某个资源访问5次,否则只能再等待下个时间段来访问。
public class SPeedLimiter {
private final static Jedis jedis = RedisPool.getRedis();
private final static String SPEED_LIMIT_KEY = "speed_limit_str::%s";
public static void execute(String ip) {
Long count = jedis.incr(String.format(SPEED_LIMIT_KEY, ip));
if (count > 5) {
System.out.println("操作满5次,请稍后再操作");
return;
}
System.out.println("操作成功:" + ip);
}
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
execute("127.0.0.1");
}
}
}
2 散列(哈希表)Hash
Redis的散列表是一种存储键值对的数据结构。类似于Java的HashMap。但是其键和值只能是字符串(或字节)类型,不能嵌套。
赋值与读取 | 单个:HSET(也可以批量设置)、HSETNX、HGET 批量操作:HMSET、HMGET |
数值运算 | HINCRBY、HINCRBYFLOAT |
散列 | 字段相关:HSTRLEN(字段值字节长度)、HEXISTS(检查字段是否存在)、HDEL(删除字段) 散列相关:HLEN(字段数量)、HKEYS(获取所有字段)、HVALS(获取所有值)、HGETALL(所有字段和值) |
表 散列数据结构相关命令
2.1 与字符串结构对比
字符串 | 字符串键命令提供的操作比散列键更为丰富; 键过期功能针对的是整个键,用户无法为散列中不同字段设置不同的过期时间。 |
散列 | 只需在数据库里创建一个键,就可以把任意多的字段和值聚合在一起; 可以有效地组织起相关的多项数据,让程序产生给更容易操作的数,使得针对数据的批量操作变得更方便。 |
表 散列与字符串数据结构对比
2.2 示例
短网址生成:遇到很长的网址时,我们会将其转换为相应的短网址,用这个短网址访问的内容和原网址是一样的。
原理:将需要转换的网址与数据库的id相关联,然后把这个id值转换为特定的字符串。这样就使用“ 服务 + /特定字符串”的形式进行访问时,后端根据这个字符串查找原网址,然后跳转至原网址。
public class ShortURLGenerator {
private final static String SHORT_URL_ID_COUNTER_KEY = "short_url_id_counter";
private final static String SHORT_URL_HASH_KEY = "short_url_hash";
private final static String START_URL = "http://localhost:8080/";
private final static Jedis jedis = RedisPool.getRedis();
public static String generateShortUrl(String targetUrl) {
Long id = jedis.incr(SHORT_URL_ID_COUNTER_KEY);
jedis.hset(SHORT_URL_HASH_KEY,id.toString(),targetUrl);
return START_URL + id;
}
public static String resolutionUrl(String url) {
if (url == null || !url.startsWith(START_URL)) return null;
String target = url.substring(START_URL.length());
return jedis.hget(SHORT_URL_HASH_KEY,target);
}
public static void main(String[] args) {
System.out.println(resolutionUrl("http://localhost:8080/1"));
System.out.println(resolutionUrl("http://localhost:8080/2"));
System.out.println(resolutionUrl("http://localhost:8080/3"));
System.out.println(resolutionUrl("2http://localhost:8080/1"));
}
}
3 列表List
列表是一种线性的有序结构,可以按照元素被推入列表中的顺序来存储元素。这些元素既可以是文字,也可以是二进制,并且元素可重复。
推入弹出 | 推入:LPUSH、RPUSH、LPUSHX(只对已存在的列表执行推入操作)、RPUSHX 弹出:LPOP、RPOP 将源列表最右端元素弹出,然后将该元素左推入目标列表:RPOPLPUSH |
列表 | 长度:LLEN 获取单个元素:LINDEX 获取元素列表:LRANGE 覆盖:LSET 插入:LINSERT 修剪:LTRIM 删除:LREM |
阻塞 | BLPOP、BRPOP、BRPOPLPUSH |
表 列表数据结构相关命令
3.1 示例
带有阻塞功能的消息队列:一个线程创建一个简单消息接收者,在没有消息时,这个线程会被阻塞,当消息出现时,该接收者将打印这条消息。
public class BlockMessageQueue {
private final static String BLOCK_MESSAGE_QUEUE_KEY = "block_message_queue";
public static void main(String[] args) {
Runnable run1 = () -> {
System.out.println("具有阻塞功能的消息队列读取");
System.out.println(RedisPool.getRedis().brpop(5,BLOCK_MESSAGE_QUEUE_KEY));;
System.out.println("阻塞功能end");
};
Runnable run2 = () -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("写入进程2");
RedisPool.getRedis().lpush(BLOCK_MESSAGE_QUEUE_KEY,"run2");
};
Runnable run3 = () -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("写入进程3");
RedisPool.getRedis().lpush(BLOCK_MESSAGE_QUEUE_KEY,"run3");
};
Thread thread1 = new Thread(run1);
Thread thread2 = new Thread(run2);
Thread thread3 = new Thread(run3);
thread1.start();
thread2.start();
thread3.start();
}
}
原文地址:https://blog.csdn.net/qq_25308331/article/details/144297575
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!