Redis学习笔记(1)
Redis键(key)
命令 | 描述 |
---|---|
keys * | 查看当前库所有key |
exists <key> | 判断某个key是否存在 |
type <key> | 查看key是什么类型 |
del <key> | 删除指定的key数据 |
expore <key> <time> | 为给定的key设置过期时间time(单位秒) |
ttl <key> | 查看还有多少秒过期,-1表示永不过期,-2表示已过期 |
select <index> | 切换当前数据库(共16个数据库,0为默认库) |
dbsize | 查看当前数据库key的数量 |
flushdb/flushall | 清空当前库/全部库 |
Redis字符串(String)
String
类型是二进制安全的,意味着Redis的String
可包含任何数据,比如jpg图片或者序列化的对象。
一个Redis中字符串value最多可以是512M。
命令 | 描述 |
---|---|
set <key> <value> | 添加键值对 |
get <key> | 查询对应键值 |
append <key> <value> | 将给定的value追加到原值的末尾 |
strlen <key> | 获得key的长度 |
setnx <key> <value> | 只有在key不存在时,才能设置key的值 |
incr/decr <key> | 将key中储存的数字值增/减(+/-) 1 |
incrby/decrby <key> <步长> | 将key中储存的数字值增/减,自定义步长 |
mset <key1><value1><key2><value2>… | 同时设置一个或多个key-value对 |
mget <key1><key2>… | 同时获取一个或多个value |
msetnx <key1><value1><key2><value2>… | 同时设置一个或多个key-value对,当且仅当所有给定key都不存在 |
getrange <key> <起始位置><结束位置> | 获得值的范围(全部:get key 0 -1) |
setrange <key><起始位置><value> | 用value覆写key所储存的字符串值,从起始位置开始(索引从0开始) |
setnx <key> <过期时间><value> | 设置键值的同时,设置过期时间(单位秒) |
getset<key><value> | 设置新值同时获得旧值 |
Redis列表(List)
单键多值,双向链表
命令 | 描述 |
---|---|
lpush/rpush <key> <value1> <value2>… | 从左边/右边插入一个或多个值 |
lpop/rpop <key> | 从左边/右边吐出一个值。 |
rpoplpush <key1> <key2> | 从key1列表右边吐出一个值,查到key2列表右边 |
lrange <key> <start> <stop> | 按照索引下标获得元素(从左到右)<br>(全部:lrange key 0 -1) |
lindex <key> <index> | 按照索引下标获得元素(从左到右) |
llen <key> | 获得列表的长度 |
linsert <key> before/after <value> <newvalue> | 在value的前/后面插入newvalue值 |
lrem <key> <n> <value> | 从左边删除n个value(从左到右) |
lset <key> <index> <value> | 将列表key下标为index的值替换成value |
Redis集合(Set)
Redis的集合Set
是String类型的无序集合,与list类似是一个列表的功能,但Set
可以自动数据排重。底层是一个value为null
的hash表,所以添加、删除、查找的复杂度都为O(1)
。
命令 | 描述 |
---|---|
sadd <key> <member1> <member2>… | 将一个或多个member元素加入到集合key中,已存在的member将被忽略 |
smembers <key> | 取出该集合的所有值 |
sismember <key> <member> | 判断集合key是否含有该member值,有则1,无则0 |
scard <key> | 返回该集合的元素个数 |
srem <key> <member1> <member2>… | 删除集合中的某个元素 |
spop <key> | 随机从该集合中吐出一个值 |
srandmember <key> <n> | 随机从该集合中取出n个值。值不会从集合中删除 |
smove <source> <destination> <member> | 把集合中的一个member值从一个集合移动到另一个集合中 |
sinter/sunion <key1> <key2> | 返回两个集合的交集/并集元素 |
sdiff <key1> <key2> | 返回两个集合的差集元素(key1中的,不包含key2中的) |
Redis哈希(Hash)
Redis的Hash
是一个String类型的field和value的映射表,hash适合用于存储对象,类似Java中的Map<String, Object>
。
当key存储的value过多时,往往为了提高查询效率,例如用户ID为key,field有姓名、年龄、职业等信息,这是我们可以选择通过key(用户ID)+field(属性标签)就可以操作对应属性的数据。
类似于map套娃:<String, <Map<key, value>>>
命令 | 描述 |
---|---|
hset <key> <field> <value> | 给key集合中的field键赋值value,例:hset user:001 name zeker |
hget <key> <field> | 从key集合中的fild中取出value |
hmset <key> <field1> <value1> <field2> <value2>… | 批量设置hash的值 |
hexists <key> <field> | 查看哈希表key中,给定field是否存在 |
hkeys <key> | 列出该hash集合的所有field |
hvals <key> | 列出该hash集合的所有value |
hincrby <key> <field> <increment> | 为哈希表key中的field的值加上增量increment(例:1 -1) |
hsetnx <key> <field> <value> | 将哈希表key中的field的值设置为value,当且仅当field不存在 |
Redis有序集合(Zset)
Redis有序集合Zset
与普通集合Set相似,都是一个没有重复元素的字符串集合。
不同之处在于有序集合Zset
的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。
集合中的成员是唯一的,但评分可以是重复的。这里例子可以为:排行榜
命令 | 描述 |
---|---|
zadd <key> <score1> <member1> <score2> <member2>… | 将一个或多个memeber元素及其score值加入到有序集key中 |
zrange <key> <start> <stop> [withscores] | 返回有序集key中,下标在start与stop之间的元素(withscores可让分数与值返回到结果集 |
zrangebyscore key min max [withscoers] [limit offset count] | 返回有序集key中,所有score值介于min和max之间(包括等于min或max)的成员,有序集成员按score值递增(从小到大)次序排列 |
zrevrangebyscore key max min [withscoers] [limit offset count] | dev:反转。意思同上,次序从大到小排列 |
zincrby <key> <increment> <member> | 为元素member的score加上增量increment |
zrem <key> <member> | 删除该集合下指定值的元素 |
zcount <key> <min> <max> | 统计该集合中分数区间内的元素个数 |
zrank <key> <member> | 返回该元素member在集合中的排名,从0开始 |
Zset底层中使用了两种数据结构:hash表与跳跃表
- hash表,作用就是关联元素value和权重score,保障元素value的唯一值,可以通过元素value找到相应的score值。
- 跳跃表,目的在于给元素value排序,根据score的范围获取元素列表,从而比普通列表查询效率更快。
Redis新数据类型
Bitmaps
Redis提供Bitmaps
这个”数据类型“可以实现对位的操作:
(1)Bitmaps
本身不是一种数据结构,实际上就是字符串,但是它可以对字符串的位进行操作。、
(2)Bitmaps
单独提供了一套命令,所以在Redis中使用Bitmaps
和使用字符串的方法不太相同。可以Bitmaps
想象成一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在Bitmaps
中叫做偏移量。单个Bitmaps
的最大长度是512MB
,即2^32
个比特位。
命令 | 描述 | |
---|---|---|
setbit <key> <offset> <value> | 设置Bitmaps中某个偏移量offset的值value | |
getbit <key> <offset> | 获取Bitmaps中某个偏移量offset的值value | |
bitcount <key> [start end] | 统计字符串从start字节到end字节比特值为1的数量 | |
bitop and(or/not/xor) <destkey> [key…] | 多个Bitmaps的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destkey中 |
HyperLogLog
解决基数问题方案:
(1)数据存储在MySQL表中,使用distinct count计算不重复个数
(2)使用Redis提供的hash、set、bitmaps等数据结构来处理
以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的。
为了能够降低一定的精度来平衡存储空间,Redis推出了HyperLogLog,一种用来做基数统计的算法。
其优点在于:
在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
每个HyperLogLog
键只需要花费 12 KB
内存,就可以计算接近 2^64
个不同元素的基数
。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
基数 = 数据集元素个数 - 重复数字个数
但是,因为HyperLogLog
只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog
不能像集合那样,返回输入的各个元素。
命令 | 描述 |
---|---|
padd <key> <element> [element…] | 添加指定元素element到HyperLogLog中 |
pfcount <key> [key…] | 计算key中的基数 |
pfmerge <destkey> <sourcekey> [sourcekey…] | 将一个或多个key合并后的结果储存在另一个destkey中 |
Geospatital
Redis GEO
,Geographic,地理信息的缩写。
主要用于存储地理位置信息,即经纬度(二维坐标),基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。
命令 | 描述 |
---|---|
geoadd <key> <longitude> <latitude> <member> [longitude latitude member…] | 添加地理位置(经度、维度、名称)(有效经度:-180度到180度;有效纬度:-85.05112878度到85.05112878度) |
geopos <key> <member> [member…] | 获得指定地区member的坐标 |
geodist <key> <member1> <member2> [m|km|ft|mi] | 获取两个指定地区位置之间的直线距离(单位:米|千米|英尺|英里,默认单位米) |
georadius <key> <longitude> <latitude> radius m|km|ft|mi | 以给定的经纬度为中心找出某一半径radius内的元素 |
Redis事务命令
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
命令 | 描述 |
---|---|
multi | 标记一个事务块的开始,开始对命令的组队阶段 |
exec | 执行所有事务块内的命令,开始执行阶段 |
discard | 取消事务,放弃执行事务块内的所有命令 |
watch <key> [key…] | 监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令锁改动,那么事务将被打断 |
unwatch | 取消watch命令对所有key的监视 |
组队阶段中某个命令出现了命令报错,执行阶段整个的所有队列都会被取消。
而当组队阶段无报错,执行阶段某一命令出现了命令报错,则只有报错的命令不会被执行,其他命令不受影响。
当出现事务冲突时,Redis往往呈现出乐观锁
的形式进行处理,即在使用完数据修改版本号
等机制,提高吞吐量,而Redis就是利用这种check-and-set
机制实现事务。
事务三特性
特性 | 描述 |
---|---|
单独的隔离操作 | 事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断 |
没有隔离级别的概念 | 队列中的命令没有提交之前都不会实际地被执行,因为事务提交前任何指令都不会被实际执行 |
不保证原子性 | Redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚 |