《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
连接 redis:redis-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 所对应的 valueexists key
判断该键值对是否存在del key
根据 key 删除键值对mset key1 value1 key2 value2...
储存多个 key valuemget key1 key2
根据多个 key ,返回一个 value 列表expire key second
设置某个 key 的过期时间setex key second value
等价于 set+expiresetnx key value
如果 key 存在就不执行,不存在则执行incr key
value 为整数时 +1incrby 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 所对应的 valuehmset hashKey key1 value1 key2 value2
批量 sethincrby 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
储存一个 setsmembers books
返回 set 内所有值,无序sismember key value
查询某个 value 是否存在,存在返回 1,否则返回 0scard 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 ,传入 scorezrange key 0 -1
按 score 排序列出,参数区间为排名范围zrevrange key 0 -1
按 score 逆序列出,参数区间为排名范围zcard key
获取 zset 长度zscore key value
获取指定 value 的 score ,内部使用 double 类型进行存储 scorezrank key value
获取 value 所在排名zrangebyscore key findex eindex
根据分值区间遍历 zsetzrangebyscore key -inf index withscores
根据分值区间遍历 zset,同时返回分值,-inf 为负无穷大zrem key value
删除指定 value
今日未解决问题
- redis 中的 rehash
- redis 中的 rehash 与 java 中 rehash 的区别
- 跳跃列表
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于