redis常用数据结构解析
Redis是一个开源的Key-Value存储引擎,它支持string、hash、list、set和sorted set等多种值类型。由于其卓越的性能表现、丰富的数据类型及稳定性,广泛用于各种需要k/v存储的场景。甚至在一些分布式缓存系统中,也用它作为底层存储引擎。本文对redis最常用的数据类型进行剖析,从而让使用者在各自场景下选择合适的数据类型,从而发挥其最好的优势。
1、String
String是最常用的一种数据类型,普通的k/v存储都可以归为此类,内部由sds.h定义。在类型的设计上,除了包含字符数组buf,还会额外存储实际字符串的长度以及buf的剩余空间,从而提供更灵活的管理方式。特别需要提到的是,redis自己管理内存,从而自身可以掌握更多关于内存的信息,提高内存分配的性能以及作为其它功能的依据。此外,该结构还提供了一些字符串相关的操作函数,功能丰富,实现透明,使用方便。
常用命令:
|
命令 |
时间复杂度 |
描述 |
返回值 |
|
APPEND |
O(1) |
如果该Key已经存在,APPEND命令将参数Value的数据追加到已存在Value的末尾。如果该Key不存在,APPEND命令将会创建一个新的Key/Value。 |
追加后Value的长度 |
|
INCR |
O(1) |
将指定Key的Value原子性的递增1。如果该Key不存在,其初始值为0,在incr之后其值为1。如果Value的值不能转换为整型值,该操作将执行失败并返回相应的错误信息。 |
递增后的Value值 |
|
INCRBY |
O(1) |
将指定Key的Value原子性的增加increment。如果该Key不存在,其初始值为0,在incrby之后其值为increment。如果Value的值不能转换为整型值,该操作将执行失败并返回相应的错误信息。 |
增加后的Value值 |
|
DECR |
O(1) |
将指定Key的Value原子性的递减1。如果该Key不存在,其初始值为0,在decr之后其值为-1。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。 |
递减后的Value值。 |
|
DECRBY |
O(1) |
将指定Key的Value原子性的减少decrement。如果该Key不存在,其初始值为0,在decrby之后其值为-decrement。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。 |
减少后的Value值。 |
|
GET |
O(1) |
获取指定Key的Value。如果与该Key关联的Value不是string类型,Redis将返回错误信息。 |
与该Key相关的Value,如果该Key不存在,返回nil。 |
|
SET |
O(1) |
设定该Key持有指定的字符串Value,如果该Key已经存在,则覆盖其原有值。 |
返回"OK" |
2、Hash
Hash是一个string类型的field和value的映射表,由dict.h定义。一个key可对应多个field,一个field对应一个value。将一个对象存储为hash类型,较于每个字段都存储成string类型更能节省内存,并且可以更方便的存取整个对象。hash内部存储的value为一个hashMap,并提供了直接存取这个Map成员的接口。
举个例子:我们要存储一个用户详细信息,就对每个用户设置一个userID作为key,而存储的value包含了包括姓名name,年龄age,生日birth,住址addr等信息。如果用普通的k/v结构存储,一般就是userID与value中的每一项组合作为key,而对应的内容作为value。如通过命令
mset user1_name ”张三” user1_age 18 user1_addr “杭州”
这种模式,在数据量大的时候,存在明显的内存浪费。而redis提供的hash结构就很好的解决了这个问题。对于上面的例子,通过执行命令hmset user1 name ”张三” age 18 addr “杭州”
user1作为key,而name、age、birth等作为属性。如此,便通过key+field的方式,避免了数据的重复存储。
提到Hash结构,不得不说的是key的冲突解决办法和哈希表的扩容方案。在Redis中,在冲突发生时,采取的是链式冲突解决办法。另外,redis采用了双哈希表结构(ht[2])。简单来说,就是初始k/v保存在ht[0]中,当冲突严重时,将ht[1]中桶的大小设置为ht[0]的两倍,并逐步将ht[0]中的元素迁移到ht[1]。等到所有元素都迁移完成后,再将ht[0]与ht[1]交换地址。
常用命令:
|
命令 |
时间复杂度 |
描述 |
返回值 |
|
HSET |
O(1) |
为指定的Key设定Field/Value对,如果Key不存在,该命令将创建新Key以参数中的Field/Value对,如果参数中的Field在该Key中已经存在,则用新值覆盖其原有值。 |
1表示新的Field被设置了新值,0表示Field已经存在,用新值覆盖原有值。 |
|
HGET |
O(1) |
返回指定Key中指定Field的关联值。 |
返回参数中Field的关联值,如果参数中的Key或Field不存,返回nil。 |
|
HEXISTS |
O(1) |
判断指定Key中的指定Field是否存在。 |
1表示存在,0表示参数中的Field或Key不存在。 |
3、List
List实现为一个双向链表,支持了反向的插入、查找和遍历,由adlist.h定义。我们可以通过push,pop操作从链表的头部或者尾部添加删除元素。在需要队列这样的数据结构时,List能提供非常丰富的接口,广泛用于缓冲队列,消息队列等应用场景。学过数据结构的朋友,对此肯定不会陌生。
常用命令:
|
命令 |
时间复杂度 |
描述 |
返回值 |
|
LPUSH |
O(1) |
在指定Key所关联的List Value的头部插入参数中给出的所有Values。如果该Key不存在,该命令将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的头部插入。如果该键的Value不是链表类型,该命令将返回相关的错误信息。 |
插入后链表中元素的数量。 |
|
RPUSH |
O(1) |
在指定Key所关联的List Value的尾部插入参数中给出的所有Values。如果该Key不存在,该命令将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的尾部插入。如果该键的Value不是链表类型,该命令将返回相关的错误信息。 |
插入后链表中元素的数量。 |
|
LPOP |
O(1) |
返回并弹出指定Key关联的链表中的第一个元素,即头部元素。如果该Key不存,返回nil。 |
链表头部的元素。 |
|
RPOP |
O(1) |
返回并弹出指定Key关联的链表中的最后一个元素,即尾部元素。如果该Key不存,返回nil。 |
链表尾部的元素。 |
|
LLEN |
O(1) |
返回指定Key关联的链表中元素的数量,如果该Key不存在,则返回0。如果与该Key关联的Value的类型不是链表,则返回相关的错误信息。 |
链表中元素的数量。 |
4、Set
Set集合类型提供的是一个列表的功能,而且是可以自动去重的。它的内部实现其实是一个value值为null的HashMap,也正是因此来使得数据去重以及判断某个成员是否在集合内等其它一些重要接口变的简单。当某些应用场景需要存储一个列表,且不想要重复的数据时,就可以选择set这个结构来处理。
常用命令:
|
命令 |
时间复杂度 |
描述 |
返回值 |
|
SADD |
O(N) |
时间复杂度中的N表示操作的成员数量。如果在插入的过程用,参数中有的成员在Set中已经存在,该成员将被忽略,而其它成员仍将会被正常插入。如果执行该命令之前,该Key并不存在,该命令将会创建一个新的Set,此后再将参数中的成员陆续插入。如果该Key的Value不是Set类型,该命令将返回相关的错误信息。 |
本次操作实际插入的成员数量。 |
|
SREM |
O(N) |
时间复杂度中的N表示被删除的成员数量。从与Key关联的Set中删除参数中指定的成员,不存在的参数成员将被忽略,如果该Key并不存在,将视为空Set处理。 |
从Set中实际移除的成员数量,如果没有则返回0。 |
|
SCARD |
O(1) |
获取Set中成员的数量。 |
返回Set中成员的数量,如果该Key并不存在,返回0。 |
|
SISMEMBER |
O(1) |
判断参数中指定成员是否已经存在于与Key相关联的Set集合中。 |
1表示已经存在,0表示不存在,或该Key本身并不存在。 |
5、Sort Set
Sort Set的功能与Set非常相似,只不过它是可以通过用户提供一个优先级参数来实现自动排序的,而Set结构不会做自动排序。Sort set内部使用HashMap和SkipList来实现数据的有序存储,保证查询的效率以及元素有序性。在某些应用场景,比如需要为某个班级的学生根据成绩来排序,就可以将优先级参数设置为成绩分数,这样在插入到这个结构时,就可以实现自动的排序。
|
命令 |
时间复杂度 |
描述 |
返回值 |
|
APPEND |
O(1) |
如果该Key已经存在,APPEND命令将参数Value的数据追加到已存在Value的末尾。如果该Key不存在,APPEND命令将会创建一个新的Key/Value。 |
追加后Value的长度 |
|
INCR |
O(1) |
将指定Key的Value原子性的递增1。如果该Key不存在,其初始值为0,在incr之后其值为1。如果Value的值不能转换为整型值,该操作将执行失败并返回相应的错误信息。 |
递增后的Value值 |
|
INCRBY |
O(1) |
将指定Key的Value原子性的增加increment。如果该Key不存在,其初始值为0,在incrby之后其值为increment。如果Value的值不能转换为整型值,该操作将执行失败并返回相应的错误信息。 |
增加后的Value值 |
|
DECR |
O(1) |
将指定Key的Value原子性的递减1。如果该Key不存在,其初始值为0,在decr之后其值为-1。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。 |
递减后的Value值。 |
|
DECRBY |
O(1) |
将指定Key的Value原子性的减少decrement。如果该Key不存在,其初始值为0,在decrby之后其值为-decrement。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。 |
减少后的Value值。 |
|
GET |
O(1) |
获取指定Key的Value。如果与该Key关联的Value不是string类型,Redis将返回错误信息。 |
与该Key相关的Value,如果该Key不存在,返回nil。 |
|
SET |
O(1) |
设定该Key持有指定的字符串Value,如果该Key已经存在,则覆盖其原有值。 |
返回"OK" |
redis常用数据结构解析的更多相关文章
- Redis常用数据结构
Redis常用数据结构包括字符串(strings),列表(lists),哈希(hashes),集合(sets),有序集合(sorted sets). redis的key最大不能超过512M,可通过re ...
- php数组去重、魔术方法、redis常用数据结构及应用场景
一.用函数对数组进行去重的方法 1.arrau_unique函数的作用 移除数组中重复的值. 将值作为字符串进行排序,然后保留每个值第一次出现的健名,健名保留不变. 第二个参数可以选择排序方式: SO ...
- Redis常用数据结构和操作
1.String 存入字符类型 Set name luowen 设置name = luowen 存储 Get name 获取设置好的name的值 Setnx name luowen 设置name键值为 ...
- Redis 常用数据结构及其控制命令整合
Redis 键值支持5种基本结构,分别是字符串,列表,哈希,集合,有序集合.每一种数据结构都有对应的取值和设值命令,辅助命令,除此之外,还有一些全局命令,用来管理Redis存储的所有 键. 全局命令 ...
- c#常用数据结构解析【转载】
引用:http://blog.csdn.net/suifcd/article/details/42869341 前言:可能去过小匹夫博客的盆油们读过这篇对于数据结构的总结,但是小匹夫当时写那篇文章的时 ...
- Redis常用命令解析——INFO, MONITOR, SLOWLOG
1. INFO info指令返回服务器相关信息,包括: server: General information about the Redis server clients: Client conne ...
- Redis 常用数据结构命令
1. 字符串(string) 增加元素 set key value [EX seconds] [PX milliseconds] [NX|XX] EX seconds:为键设置秒级过期时间 PX mi ...
- Redis五种基础与三种高级数据结构解析
记得点赞+关注呦. 前言 在 Redis 最重要最基础就属 它丰富的数据结构了,Redis 之所以能脱颖而出很大原因是他数据结构丰富,可以支持多种场景.并且 Redis 的数据结构实现以及应用场景在面 ...
- redis常用配置参数解析
本文主要总结一下redis常用的配置参数的用法: 以下参数决定redis运行方式,默认前台运行,修改为yes可以让redis以后台守护进程方式运行 daemonize no 以下参数指定redis的p ...
随机推荐
- Thunder团队第三周 - Scrum会议2
Scrum会议2 小组名称:Thunder 项目名称:i阅app Scrum Master:李传康 工作照片: 胡佑蓉在拍照,所以不在照片中. 参会成员: 王航:http://www.cnblogs. ...
- django 使用json.dumps转换queryset的datatime报错问题解决
最近在使用django做项目的时候想使用ajax来实现前后台数据的交互,但是在将数据库查询结果转换成json数据时,遇到时间格式的数据转换遇到问题,无法正确的进行转换,具体如下: 转换成json时使用 ...
- isset、is_null、empty的区别
版本:PHP 5.4 1.isset() :检测变量是否存在,测试如下: $a = false; $b = null; $c; $d = 0; $e = true; var_dump(isset($a ...
- 提升MyEclipse运行速度
修改MyEclipse.ini文件中的,将-vmargs后面的参数修改为 -Xms256m -Xmx768m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:Max ...
- 使用oledb读取excel表
string path = "C:\\Users\\aaa\\Desktop\\aa.xls"; string conn = "Provider = Microsoft. ...
- BZOJ4596:[SHOI2016]黑暗前的幻想乡——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4596 https://www.luogu.org/problemnew/show/P4336#su ...
- UVA.10474 Where is the Marble ( 排序 二分查找 )
UVA.10474 Where is the Marble ( 排序 二分查找 ) 题意分析 大水题一道.排序好找到第一个目标数字的位置,返回其下标即可.暴力可过,强行写了一发BS,发现错误百出.应了 ...
- nodejs获取文件信息,判断是文件或目录
var stat = fs.statSync(filename); console.log(stat) 输出 { dev: 0, ino: 0, mode: 33206, nlink: 1, uid: ...
- mybatis Mapper 中resultType使用方法及返回值为Map的写法
mybatis学习(七)——resultType解析 resultType是sql映射文件中定义返回值类型,返回值有基本类型,对象类型,List类型,Map类型等.现总结一下再解释 总结: resul ...
- 在Linux中新增与删除用户可以使用命令:Useradd
在Linux中新增与删除用户可以使用命令:Useradd 我们先使用man命令理解一下Useradd的用法 新增与删除用户操作需要先获取高级用户权限 输入命令:sudo -i 确定后输入高级用户密码 ...