问题:redis 跳表与红黑树的查询性能?
没错碰到这个问题的时候,笔者现在还不清楚,快表,跳表,也更不用说红黑树。不过没关系,终会进步的,沉下心,一步一个脚印来,与君共勉。
Redis 深入历险
1. String (字符串) :sds,ArrayList
① 键值对
127.0.0.1:6379[1]> set name codehole
OK
127.0.0.1:6379[1]> get name
"codehole"
127.0.0.1:6379[1]> exists name
(integer) 1
127.0.0.1:6379[1]> del name
(integer) 1
127.0.0.1:6379[1]> get name
(nil)
127.0.0.1:6379[1]>
客户端的显示情况:
用法总结:
添加:set key vlue
获取:get key
删除:del key
nil:get key 当key 不存在时
② 批量键值对:mset,mget
127.0.0.1:6379[1]> mset name1 body name2 girl name3 unknow
OK
127.0.0.1:6379[1]> mget name1 name2 name3
1) "body"
2) "girl"
3) "unknow"
③ 过期和 set 命令扩展:expire,setnx,setex
127.0.0.1:6379[1]> set name codehole
OK
127.0.0.1:6379[1]> get name
"codehole"
127.0.0.1:6379[1]> expire name 5
(integer) 1
127.0.0.1:6379[1]> get name
(nil)
127.0.0.1:6379[1]> setex name 5 codehole
OK
127.0.0.1:6379[1]> get name
"codehole"
127.0.0.1:6379[1]> get name
(nil)
127.0.0.1:6379[1]> setnx name codehole
(integer) 1
127.0.0.1:6379[1]> get name
"codehole"
127.0.0.1:6379[1]> setnx name holycoder
(integer) 0
127.0.0.1:6379[1]> get name
"codehole"
用法总结:
设置过期时间的两种方式:
添加键值对后:expire key time
添加键值时:setex key time value
命令扩展:
setex :添加键值对的同时设置有效期
setnx :key 不存在时设置
其中 setnx 也可以写成:set key value nx
set key value xx :key 存在时设置
④ 计数 incr, incrby num
127.0.0.1:6379[1]> set age 30
OK
127.0.0.1:6379[1]> incr age
(integer) 31
127.0.0.1:6379[1]> incrby age 5
(integer) 36
127.0.0.1:6379[1]> incrby age -5
(integer) 31
用法总结:
incr:incr key 自增1不带参数
incrby:incrby key value 参数 value 可正可负
2. list(列表) LinkedList ,异步队列
① 右边进左边出:队列
127.0.0.1:6379[1]> rpush books python java golang
(integer) 3
127.0.0.1:6379[1]> llen books
(integer) 3
127.0.0.1:6379[1]> lpop books
用法总结:
右侧添加元素:rpush list_key value1 value2 value3 …
获取列表元素:llen list_key
问题:是否支持 rlen ?
help @list 之后发现不支持,为什么不支持 rlen 呢 ?深入学习的时候看看源码,先记下来
弹出列表元素:lpop list_key 或 rpop list_key
② 右边进右边出:栈
用法同上
127.0.0.1:6379[1]> lrange books 0 -1
1) "java"
127.0.0.1:6379[1]> rpush books python java golang
(integer) 4
127.0.0.1:6379[1]> lrange books 0 -1
1) "java"
2) "python"
3) "java" # list 是可以有重复元素的
4) "golang"
用法同上,list 是支持 rpush,lpush,rpop,lpop的,而且可以将添加和移除操作任意组合
127.0.0.1:6379[1]> rpush boo1 a b c
(integer) 3
127.0.0.1:6379[1]> lpop # 缺少key
(error) ERR wrong number of arguments for 'lpop' command
127.0.0.1:6379[1]> lpop boo1
"a"
127.0.0.1:6379[1]> lpush boo1 d e f
(integer) 5
127.0.0.1:6379[1]> lrange boo1 0 -1
1) "f"
2) "e"
3) "d"
4) "b"
5) "c"
127.0.0.1:6379[1]> rpop boo1
"c"
③ 慢操作 lindex 相当于Java链表的 get(int index)
127.0.0.1:6379[1]> lrange books 0 -1
1) "java"
2) "python"
3) "java"
127.0.0.1:6379[1]> lindex books 4
(nil)
127.0.0.1:6379[1]> lindex books -1
"java"
127.0.0.1:6379[1]> lindex books 0
"java"
127.0.0.1:6379[1]> ltrim books 1 0
OK
127.0.0.1:6379[1]> llen books
(integer) 0
在 RDM 上的显示
用法总结:
获取列表中index位置上的参数:lindex list_key index
需要注意的是:index 大于 list 索引 会返回 nil;index 为负时,会返回从尾部开始计数的第index个元素
截取或清空列表:ltrim list_key ihead itail 当 itail < ihead 时区间返回为负,会清空列表
④ 快速列表 quicklist :ziplist + linkedlist
3. hash(字典)
127.0.0.1:6379[1]> hset books java "think in java"
(integer) 1
127.0.0.1:6379[1]> hset books python "python cookbook"
(integer) 1
127.0.0.1:6379[1]> hset books golang "concurrency in go"
(integer) 1
127.0.0.1:6379[1]> hgetall books
1) "java"
2) "think in java"
3) "python"
4) "python cookbook"
5) "golang"
6) "concurrency in go"
127.0.0.1:6379[1]> hlen books
(integer) 3
127.0.0.1:6379[1]> hget books java
"think in java"
127.0.0.1:6379[1]> hset books golang "learning go programming"
(integer) 0
127.0.0.1:6379[1]> hget books golang
"learning go programming"
127.0.0.1:6379[1]> hmset books java "effective java" python "learning python" golang "modern golagn programming"
OK
127.0.0.1:6379[1]> hmget books java python
1) "effective java"
2) "learning python"
RDM 客户端查看 hash 结构的存储形式
用法总结:
添加单个:hset key field value
添加多个:hmsetf key field1 value1 field2 value2…
获取单个:hget key field
获取多个:hmget key field1 field2
获取所有:hgetall key
4. set(集合)
127.0.0.1:6379[1]> sadd book python
(integer) 0
127.0.0.1:6379[1]> sadd book jaba golang
(integer) 2
127.0.0.1:6379[1]> smembers book
1) "golang"
2) "jaba"
3) "python"
127.0.0.1:6379[1]> sismember book java
(integer) 0
127.0.0.1:6379[1]> spop book 1
1) "a"
127.0.0.1:6379[1]> spop book 0
(empty array)
127.0.0.1:6379[1]> smembers book
1) "b"
2) "golang"
127.0.0.1:6379[1]> spop book 2
1) "b"
2) "golang"
127.0.0.1:6379[1]> smembers book
(empty array)
用法总结:help @set
添加单个或多个:sadd key mermber1 member2…
判断set中是否有指定元素:sismember key memberx
删除元素:spop key count 其中 count 可以 > 1 删除时随机删除
使用场景:抢购优惠券时,用 set 保存已下单的用户 id,避免用户重复下单
5. zset(有序列表) :SortedSet + HashMap
127.0.0.1:6379[1]> zadd alpha 9.0 "a"
(integer) 1
127.0.0.1:6379[1]> zadd alpha 8.9 "b"
(integer) 1
127.0.0.1:6379[1]> zadd alpha 8.6 "c"
(integer) 1
127.0.0.1:6379[1]> zrange alpha 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379[1]> zrevrange alpha 0 -1
1) "a"
2) "b"
3) "c"
127.0.0.1:6379[1]> zcard alpha
(integer) 3
127.0.0.1:6379[1]> zscore alpha "b"
"8.9000000000000004"
127.0.0.1:6379[1]> zrank alpha "b"
(integer) 1
127.0.0.1:6379[1]> zrem alpha "c"
(integer) 1
用法总结:
添加:zadd key score obj
删除:zrem key obj
排序:zrange key ihead itail 按score 升序排序,ihead itail 为参数区间
逆序:zreverange key ihead itail 按 score 降序排序
统计:zcard key
查看 score :zscore key obj
查看 rank :zrank key obj
开篇问题的解答:
so,了解下 redis 跳表 和 红黑树再解答