Redis 五大基础数据结构

本贴最后更新于 1653 天前,其中的信息可能已经时移世异

《Redis 深度历险》读书笔记 -- 之基本数据结构

markdown 语法学习:https://www.jianshu.com/p/191d1e21f7ed

一 :redis 安装与启动

redis 下载与安装参考 博客:https://www.cnblogs.com/jylee/p/9844965.html

在将 redis 解压缩后的目录下,打开 cmd
redis 服务启动命令 : redis-server.exe redis.windows.conf
连接 redisredis-cli.exe -h 127.0.0.1 -p 6379
或者直接在文件夹中打开 redis-cli.exe
如果没配置环境变量的话连接 redis 的指令,必须在 redis 解压路径下打开 cmd


二 : Redis 基本数据类型

参考教程:https://www.runoob.com/redis/redis-data-types.html
参考书籍:https://book.douban.com/subject/30386804/
我这不能算参考了,基本上算是比着书敲了一遍,第一次写博文,也分不太清重点不重点的,见谅。见谅。。

1、String(字符串)
  • 简介:String 是 redis 最基本,最简单的数据类型,内部就是一个字符数组 。redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一的 key 值来获取相应的 value 数据。(key 都是字符串,value 有五种表示)key-value,最大可存储 512M
  • 特性: String 可以包含任何数据,二进制安全,如 jpg 图片类型,java 序列化对象
  • 应用: 缓存用户信息

Redis 的字符串是动态的、可以修改的,内部机构的实现类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配

基本操作

键值对:相当于字典的 key、value,支持简单的 crud,下面的 name--key codehole--value

127.0.0.1:6379> set name codehole
OK
127.0.0.1:6379> get name
"codehole"
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)

批量键值对 : 可对多个字符串进行批量操作,节省网络耗时开销

127.0.0.1:6379> set name1 codehole
OK
127.0.0.1:6379> set name2 holycoder
OK
127.0.0.1:6379> mget name1 name2 name3
1) "codehole"
2) "holycoder"
3) (nil)
127.0.0.1:6379> mset name1 boy name2 girl name3 unkonwn
OK
127.0.0.1:6379> mget name1 name2 name3
1) "boy"
2) "girl"
3) "unkonwn"

过期和 set 命令扩展 :可对 key 设置过期时间,到时间自动删除,常用做控制缓存的实效时间

127.0.0.1:6379> set name codehole
OK
127.0.0.1:6379> expire name 5 #设置name的过期时间5秒
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> setex name 5 codehole #set 与expire 结合起来用
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> setnx name codehole #如果name不存在就执行set创建
(integer) 1
127.0.0.1:6379> get name
"codehole"
127.0.0.1:6379> setnx name holycoder #如果存在就不执行
(integer) 0
127.0.0.1:6379> get name
"codehole"

计数 :若 value 是整数 , 还可进行自增操作,范围在 signed long 最大值与最小值之间

127.0.0.1:6379> set age 30
OK
127.0.0.1:6379> incr age
(integer) 31
127.0.0.1:6379> incrby age 5
(integer) 36
127.0.0.1:6379> incrby age -5
(integer) 31

基本操作整理

  • set key value 储存一个键值对
  • get key 根据 key 获得该 key 所对应的 value
  • exists key 判断该键值对是否存在
  • del key 根据 key 删除键值对
  • mset key1 value1 key2 value2... 储存多个 key value
  • mget key1 key2 根据多个 key ,返回一个 value 列表
  • expire key second 设置某个 key 的过期时间
  • setex key second value 等价于 set+expire
  • setnx key value 如果 key 存在就不执行,不存在则执行
  • incr key value 为整数时 +1
  • incrby key +-number value +-number

2、Hash(哈希字典)

在看这一部分时,讲到了 rehash,以及 redis 中的 rehash 与 java 中 rehash 的区别,这里没看懂,也不清楚 rehash 是什么,回头需要再补一补。

  • 简介: 键值对集合,相当于 Java 语言中的 HashMap,无序字典,数组 + 链表的二维结构
  • 特性: 适合存储对象,可以只更新 map 中的某个属性值而不用取出整个 map
  • 应用: 可以用作存储用户信息,hash 可以对用户结构中的每个字段单独存储,获取时可按需获取

hash 结构的存储消耗要高于单个字符串,到底要使用 hash 还是字符串需要根据实际情况再三权衡

基本操作
127.0.0.1:6379> hset books java "think in java"
(integer) 1
127.0.0.1:6379> hset books golang "concurrency in go"
(integer) 1
127.0.0.1:6379> hset books python "python cookbook"
(integer) 1
127.0.0.1:6379> hgetall books
1) "java"
2) "think in java"
3) "golang"
4) "concurrency in go"
5) "python"
6) "python cookbook"
127.0.0.1:6379> hlen books
(integer) 3
127.0.0.1:6379> hget books java
"think in java"
127.0.0.1:6379> hset books golang "learning go programming"
(integer) 0
127.0.0.1:6379> hget books golang
"learning go programming"
127.0.0.1:6379> hmset books java "effective java" python "learning python"
OK

基本操作整理

  • hset hashKey key value 储存一个 hash 如果字符串包含空格,要用引号引起来,若 hset 相同的 key 的 value ,则视为更新操作
  • hgetall hashKey 返回 hash 内所有 key value(key 与 value 间隔出现)
  • hlen hashKey 返回 hash 的长度
  • hget hashKey key 从 hashKey 内获取 key 所对应的 value
  • hmset hashKey key1 value1 key2 value2 批量 set
  • hincrby hashKey key number value 是数字的的可进行计数

3、List(列表)
  • 简介: 链表(双向链表),相当于 java 中的 LinkedList
  • 特性: 增删快,时间复杂度为 O(1),但是索引定位很慢,为 O(n), 提供了操作某一段元素的 API
  • 应用: 最新的消息,排行榜等时间线相关的,常用做异步队列

当列表弹出了最后一个元素之后,该数据结构被自动删除,内存被回收

基本操作

右边进左边出:队列先进先出,常用做消息排队和异步逻辑处理,确保了元素的访问顺序性

127.0.0.1:6379> rpush books python java golang
(integer) 3
127.0.0.1:6379> llen books
(integer) 3
127.0.0.1:6379> lpop books
"python"
127.0.0.1:6379> lpop books
"java"
127.0.0.1:6379> lpop books
"golang"
127.0.0.1:6379> lpop books
(nil)

右边进右边出:栈后进后出,业务中并不太常见

127.0.0.1:6379> rpush books python java golang
(integer) 3
127.0.0.1:6379> rpop books
"golang"
127.0.0.1:6379> rpop books
"java"
127.0.0.1:6379> rpop books
"python"
127.0.0.1:6379> rpop books
(nil)

慢操作

127.0.0.1:6379> rpush books python java golang
(integer) 3
127.0.0.1:6379> lindex books 1 #同java链表的get(index),需要对链表进行遍历
"java"
127.0.0.1:6379> lrange books 0 -1 #获取所有元素
1) "python"
2) "java"
3) "golang"
127.0.0.1:6379> ltrim books 1 -1 #保留区间内值
OK
127.0.0.1:6379> lrange books 0 -1
1) "java"
2) "golang"
127.0.0.1:6379> ltrim books 1 0 #清空列表,因为长度为负
OK
127.0.0.1:6379> llen books
(integer) 0

基本操作整理

  • rpush key value1 value2 value3 储存一个列表,从右边进
  • llen key 返回列表长度
  • lpop key 从 key 列表中左边弹出一个值,并清内存
  • rpop 从列表右边弹出一个值,并清内存
  • lindex key index 根据 index 获得 key 列表中的值,O(n)
  • lrange key key findex eindex 根据区间获取列表值,返回列表,O(n)
  • ltrim books findex eindex 根据区间保留列表中的值

4、Set(集合)
  • 简介: 哈希表的实现,元素不重复,无序,相当于 java 中的 hashSet。
  • 特性: 增删查复杂度都为 O(1) , 为集合提供了求交、并、差等操作
  • 应用: 共同好友,统计网站独立 ip,某活动的中奖 id

内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 null。
当集合中的最后一个元素被移除之后秘书局结构被自动删除,内存被回收

基本操作
127.0.0.1:6379> sadd books python
(integer) 1
127.0.0.1:6379> sadd books python
(integer) 0
127.0.0.1:6379> sadd books java golang
(integer) 2
127.0.0.1:6379> smembers books
1) "golang"
2) "java"
3) "python"
127.0.0.1:6379> sismember books java
(integer) 1
127.0.0.1:6379> sismember books rust
(integer) 0
127.0.0.1:6379> scard books
(integer) 3
127.0.0.1:6379> spop books
"python"
127.0.0.1:6379> scard books
(integer) 2

基本操作整理

  • sadd key value 储存一个 set
  • smembers books 返回 set 内所有值,无序
  • sismember key value 查询某个 value 是否存在,存在返回 1,否则返回 0
  • scard key 获取 set 长度
  • spop key 从 set 中弹出一个值

5、zSet(有序集合/有序列表)
  • 简介: 将 Set 中的 value 元素增加了一个权重 score 元素,set 内元素按 score 排序。类似于 java 中的 sortedSet 和 HashMap 的结合体
  • 特性: 数据插入集合时,已经进行了排序
  • 应用: 排行榜 ,储存学生成绩 ,粉丝列表 , 带权重的消息队列

内部实现是一种叫作“跳跃列表”的数据结构
zset 中最后一个 value 被移除后,数据结构被自动删除,内存被回收

基本操作
127.0.0.1:6379> zadd books 9.0 "think in java"
(integer) 1
127.0.0.1:6379> zadd books 8.9 "java concurrency"
(integer) 1
127.0.0.1:6379> zadd books 8.6 "java cookbook"
(integer) 1
127.0.0.1:6379> zrange books 0 -1
1) "java cookbook"
2) "java concurrency"
3) "think in java"
127.0.0.1:6379> zrevrange books 0 -1
1) "think in java"
2) "java concurrency"
3) "java cookbook"
127.0.0.1:6379> zcard books
(integer) 3
127.0.0.1:6379> zscore books "java concurrency"
"8.9000000000000004"
127.0.0.1:6379> zrank books "java concurrency"
(integer) 1
127.0.0.1:6379> zrangebyscore books 0 8.91
1) "java cookbook"
2) "java concurrency"
127.0.0.1:6379> zrangebyscore books -inf 8.91 withscores
1) "java cookbook"
2) "8.5999999999999996"
3) "java concurrency"
4) "8.9000000000000004"
127.0.0.1:6379> zrem books "java concurrency"
(integer) 1
127.0.0.1:6379> zrange books 0 -1
1) "java cookbook"
2) "think in java"

基本操作整理

  • zadd key score value 储存一个 zset ,传入 score
  • zrange key 0 -1 按 score 排序列出,参数区间为排名范围
  • zrevrange key 0 -1 按 score 逆序列出,参数区间为排名范围
  • zcard key 获取 zset 长度
  • zscore key value 获取指定 value 的 score ,内部使用 double 类型进行存储 score
  • zrank key value 获取 value 所在排名
  • zrangebyscore key findex eindex 根据分值区间遍历 zset
  • zrangebyscore key -inf index withscores 根据分值区间遍历 zset,同时返回分值,-inf 为负无穷大
  • zrem key value 删除指定 value

今日未解决问题
  1. redis 中的 rehash
  2. redis 中的 rehash 与 java 中 rehash 的区别
  3. 跳跃列表
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 247 回帖 • 181 关注
  • 中间件
    4 引用 • 2 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3167 引用 • 8207 回帖 • 1 关注
  • NoSQL
    11 引用 • 4 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...