Redis学习笔记
redis环境
1 | docker pull redis:latest |
数据结构
字符串(Strings)
set`
strlen <key>
getrange <key> <start> <end>
append <key> <value>
计数incr
incrby
decr
decrby
存储对象(简单或复杂)和计数
位图setbit
getbit
散列(Hashes)
hset
hget
相关的操作还包括在同一时间设置多个域、同一时间获取多个域、获取所有的域和值、列出所有的域或者删除指定的一个域:
1 | hmset users:goku race saiyan age 737 |
列表(Lists)
对于一个给定的关键字,列表数据结构让你可以存储和处理一组值。你可以添加一个值到列表里、获取列表的第一个值或最后一个值以及用给定的索引来处理值。列表数据结构维护了值的顺序,提供了基于索引的高效操作。
1 | lpush newusers goku |
1 | keys = redis.lrange('newusers', 0, 10) |
集合(Sets)
集合数据结构常常被用来存储只能唯一存在的值,并提供了许多的基于集合的操作,例如并集。集合数据结构没有对值进行排序,但是其提供了高效的基于值的操作。
使用集合数据结构的典型用例是朋友名单的实现:
1 | sadd friends:leto ghanima paul chani jessica |
而且,我们可以查看两个或更多的人是不是有共同的朋友:
1 | sinter friends:leto friends:duncan |
甚至可以在一个新的关键字里存储结果:
1 | sinterstore friends:leto_duncan friends:leto friends:duncan |
有序集合(Sorted Sets)
最后也是最强大的数据结构是分类集合数据结构。
提供了排序功能 sorting and ranking
1 | zadd friends:duncan 70 ghanima 95 paul 95 chani 75 jessica 1 vladimir |
对于duncan
的朋友,要怎样计算出标记(score)为90或更高的人数?
1 | zcount friends:duncan 90 100 |
如何获取chani
在名单里的倒排索引值(rank)?
1 | zrevrank friends:duncan chani |
时间复杂度
常数时间复杂度O(1)
对数时间复杂度O(log(n))
线性时间复杂度O(n)
二次时间O(n^2)
指数时间O(c^n)
Round Trips and Pipelining
数据往返?批量数据?
mget命令,接受多个关键字,然后返回值:
1 | keys = redis.lrange('newusers', 0, 10) |
或者是sadd命令,能添加一个或多个成员到集合里:
1 | sadd friends:vladimir piter |
支持流式请求
1 | redis.pipelined do |
事务
Redis是单线程运行,每个命令都具有原子性
首先要执行multi
命令,紧随其后的是所有你想要执行的命令(作为事务的一部分),最后执行exec
命令去实际执行命令,或者使用discard
命令放弃执行命令。Redis的事务功能保证了什么?
- 事务中的命令将会按顺序地被执行
- 事务中的命令将会如单个原子操作般被执行(没有其它的客户端命令会在中途被执行)
- 事务中的命令要么全部被执行,要么不会执行
1 | multi |
但这样并不能避免并发问题,因为可能有多个Redis客户端在