NoSql之Redis系列一: Redis的数据类型和基本使用
Redis简介及特点
Redis是一个开源高效率的Key-Value内存数据库.
- 支持多种数据结构 string, list, set, zset, hash, 并支持push, pop, 交并差集等多种操作, 并支持数据的持久化.
- 全内存操作, 性能极高, 官方数据: read高达 110000次/s, write高达 81000次/s.
- 操作原子性, 单操作原子性, 多操作使用MULTI和EXEC指令包裹执行保证原子性.
- 支持数据持久化.
- 支持数据publish/subscribe.
- 支持master-slaver(主从)同步, 集群操作.
Redis常用数据结构及使用
启动redis-server (win)
假设redis的目录是 e:\soft\redis
- 命令行移动到redis运行目录: cd e:\soft\redis
- 启动服务端: redis-server.exe redis.conf (服务端exe 配置文件可选)
使用redis-cli操作redis
在redis运行目录执行: redis-cli -h 127.0.0.1 -p 6379 (-h, -p 默认参数就是127.0.0.1, 6379 可不写)
String 字符串常用操作
- String 是最基础的Redis数据类型, 它是二进制安全的, 意味着String可以存储任何类型的数据, 例如jpeg图像和序列化对象.
- 单个String 的最大长度是512MB
- 绝大部分操作的复杂度是O(1), 返回多个元素除外.
- 使用场景探索: 常用来做数据缓存
// 首先需要引入 Jedis 库, 启动redis 服务端
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379); // 服务器ip和端口
System.out.print(jedis.set("name", "zhaoxi")); // OK
System.out.println(" " + jedis.get("name")); // zhaoxi
System.out.print(jedis.append("name", "append")); // 12
System.out.print(" " + jedis.get("name")); // zhaoxiappend
}
Hash 哈希常用操作
- Hash 是字符串的键值对, 所以方便存储对象
- 每个hash key最多存储 2^32 - 1 个键值对.
- 新增和删除都是O(1), 其他视命令而定
- 使用场景探索: 对象的直接缓存, 不通过String存储
// 首先需要引入 Jedis 库, 启动redis 服务端
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379); // 服务器ip和端口
System.out.print(jedis.hset("user", "name", "zhaoxi")); // 1
System.out.println(" " + jedis.hset("user", "desc", "pr")); // 1
System.out.print(jedis.hget("user", "name")); // zhaoxi
System.out.println(" " + jedis.hget("user", "desc")); // pr
}
List 列表常用操作
- List 是字符串的列表(Linked List), 按照插入顺序排序. 每个字符串首尾指向前后一个字符串.
- 单个 List 的最大长度是 2^32 - 1
- Redis 从首尾插入删除元素复杂度恒定为O(1), 从首尾访问元素复杂度也是O(1), 但是访问很大的列表时, 速度很慢, 复杂度为O(n)
- 使用场景探索: 配合lpush 和ltrim , 监测一个用户最近访问的最新n 个值
// 首先需要引入 Jedis 库, 启动redis 服务端
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.lpush("list", "index1")); // 1
System.out.println(jedis.lpush("list", "index2")); // 2
System.out.println(jedis.lpush("list", "index3")); // 3
System.out.println(jedis.lrem("list", 1, "index1")); // 1
System.out.println(jedis.lrange("list", 0, -1)); // [index3, index2]
System.out.println(jedis.lpop("list")); // index3
System.out.println(jedis.lpop("list")); // index2
System.out.println(jedis.lrange("list", 0, -1)); // []
}
Set 集合常用操作
- Set 是不允许重复切无序的列表
- 单个 Set 的最大成员数 2^32 - 1个
- 向 Set 中添加, 删除, 检测元素存在时间复杂度都是O(1)
- 使用场景探索: 监测一个帖子的访问ip 地址, 每次访问的时候直接将ip 插入到set, 不用担心唯一的问题.
// 首先需要引入 Jedis 库, 启动redis 服务端
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.sadd("set#name#1", "zhaoxi", "wuyu", "mailang")); // 3
System.out.println(jedis.sadd("set#name#1", "zhaoxi")); // 0 说明已存在
System.out.println(jedis.sadd("set#name#2", "zhaoxi","yiyi")); // 2
System.out.println(jedis.sdiff("set#name#2", "set#name#1")); // [yiyi]
System.out.println(jedis.sinter("set#name#2", "set#name#1")); // [zhaoxi]
System.out.println(jedis.sunion("set#name#2", "set#name#1")); // [wuyu, mailang, zhaoxi, yiyi]
System.out.println(jedis.del("set#name#2", "set#name#1")); // 2
}
ZSet 有序集合常用操作
- ZSet 类似 Set 和 Hash 的混合体.
- 每个有序元素都和一个浮点数(分数)相关联.
- 添加,删除,查找的复杂度都是O(1)
- 使用场景探索: 游戏中的排名, 榜单.
// 首先需要引入 Jedis 库, 启动redis 服务端
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.zadd("zset#score#181229", 10, "zhaoxi")); // 1
System.out.println(jedis.zadd("zset#score#181229", 20, "yiyi")); // 1
System.out.println(jedis.zadd("zset#score#181229", 30, "wuyu")); // 1
System.out.println(jedis.zcard("zset#score#181229")); // 3
System.out.println(jedis.zincrby("zset#score#181229",5,"zhaoxi")); // 15.0
System.out.println(jedis.zrevrange("zset#score#181229", 0, -1)); // [wuyu, yiyi, zhaoxi]
System.out.println(jedis.del("zset#score#181229")); //1
}
简单总结
Redis 的数据结构丰富, 为 Redis 提供了丰富的应用场景. 所以非常受欢迎, 使用中熟练掌握所有结构, 能让我们工作如虎添翼.