redis学习(二) redis数据结构介绍以及常用命令
redis数据结构介绍我们已经知道redis是一个基于key-value数据存储的数据结构数据库,这里的key指的是string类型,而对应的value则可以是多样的数据结构。其中包括下面五种类型: 1.string?字符串string字符串类型是redis最基础的数据存储类型。string是最基础的一种数据类型,其可以拓展为某种特定类型,例如普通文本,json字符串,二进制数据等等。就本质上来说,接下来要介绍的hash,list,set等其内部最基础的组成单位依然是string,只不过redis允许使用者以一种更加高效的方式处理某种数据结构的内部单元数据,这也是redis相对于memcached的一大优势。 2.hash?散列hash散列类型也是一种key-value形式的字典数据类型,存储了key->value的映射,和redis本身一样,其依然被限制为只允许字符串类型作为key值。同时value并不支持嵌套的数据结构,而只能是字符串类型(应该是为了保证redis设计的简单性,以及高性能(嵌套结构越深,效率越低下),因此数据结构都不允许嵌套)。redis的hash类型适合存储对象,比起json字符串的形式,在仅仅访问对象的部分属性时,能够避免不必要的cpu运算和数据传输,大大的提高了效率的同时也便于进行并发时的控制。 3.list?列表list列表类型可以存储一个有序的字符串类型列表,其常用操作为从列表的首尾添加或者获得元素、获取列表某一部分的数据等。由于list类型需要支持比较高效的首尾添加和删除操作,因此其内部实现采用了双向链表,保证了首尾对称操作效率的统一。同时,借助列表也能够实现队列的功能。 4.set?集合set集合类型拥有hash的部分特性,其内部实现采用的是value为空的hashTable(散列表),因此具有高效的查询效率(O(1)时间复杂度),存储的数据具有唯一性。set类型的常用操作除了通用的添加,删除元素之外,还拥有集合类型独有的获得多个集合的交集,并集,差集的操作。 5.sorted?set?有序集合sorted set有序集合类型是和上述的set集合类型紧密相关的,顾名思义就是排序好了的集合。最大的区别在于存储数据时,除了通用的value之外,还包括了score属性作为排序的依据。有序集合同时拥有了list列表类型(有序)和set集合类型(value唯一)的特点。其和列表不同的是,有序集合类型内部实现采用的是hashTable(散列表)和skipList(跳跃表)。因此其访问位于中间部分的数据效率也比较高(O(nlogn)时间复杂度 ),而list类型访问中间部分元素的渐进意义下的时间复杂度则为O(n)。 天下没有免费的午餐,在通过散列表和跳跃表具有较快的查询速度的同时,同等数据量的情况下其消耗的内存相比双向链表为基础的list类型要高出不少,是一种空间换时间的做法,在决定使用有序集合时需要进行一定的权衡,避免不必要的系统资源浪费。 redis数据结构常用命令redis提供了非常丰富的关于数据结构操作的各种命令。redis命令原则上不区分大小写(这里默认全部大写),而key值区分大小写 限于篇幅,这里只介绍比较常用的命令,要想了解更多的细节,最好的办法还是查看redis提供的文档进行学习。 1.string?字符串 常用命令1.1 SET GETSET 接口定义:SET key "value" 接口描述:存储一个key-value键值对,如果之前key已经存在,覆盖之前的value。 GET 接口定义:GET key? ? 接口描述:通过key,返回对应的value,如果key不存在返回nil。
1.2 INCRINCR 接口定义:INCR?key 接口描述:将key对应的value增加1,并返回执行之后的数据(之前key不存在,默认value为0)。如果value无法解析为数字类型,则抛出异常。
1.3 DECRDECR 接口定义:DECR key 接口描述:将key对应的value减少1,并返回执行之后的数据(之前key不存在,默认value为0)。如果value无法解析为数字类型,则抛出异常。
1.4 INCRBY DECRBYINCRBY?接口定义: INCRBY?key "increment" 接口描述:?将key对应的value减少参数increment,并返回执行之后的数据(之前key不存在,默认value为0)。如果increment/value无法解析为数字类型,则抛出异常。 DECRBY?接口定义: DECRBY?key "decrement" 接口描述:?将key对应的value减少参数decrement,并返回执行之后的数据(之前key不存在,默认value为0)。如果decrement/value无法解析为数字类型,则抛出异常。
1.5 STRLENSTRLEN?接口定义 : STRLEN?key 接口描述:返回key对应的value的字符串长度。
1.6 APPENDAPPEND?接口定义:APPEND?key "value" 接口描述:在key对应的value后面添加后缀,并且返回执行之后value的字符串长度。
1.7?string类型其它常用命令字符串类型的常用命令还有诸如MGET(同时获取多个key的数据),MSET(同时设置多个key的数据),INCRBYFLOAT(增加一个浮点数值),DECRBYFLOAT(减少一个浮点数值),BITOP(位运算)等等。 ? 2.hash?散列?常用命令2.1? HSET HGETHSET?接口定义: HSET?key "field" "value" 接口描述:为key对应的Hash类型元素添加一个key-value键值对。 HGET?接口定义: HGET?key "field" 接口描述:获得key对应的Hash类型元素的某一field的value值。
2.2 HMSET HMGET (M代表multi,多选的含义)HMSET?接口定义: HMSET?key "field1" "value1" ["field2" "value2"?"field3" "value3" ...] 接口描述:为key对应的Hash类型元素添加一个或多个key-value键值对。 HMGET?接口定义: HMGET?key "field1" ["field2" "field3" ...] 接口描述:获得key对应的Hash类型元素一个或多个field的value值。 ? 2.3 HGETALLHGETALL?接口定义: HGETALL?key 接口描述:获得key对应的Hash类型元素的所有key以及value值。
2.4 HEXISTSHEXISTS?接口定义: HEXISTS?key "field" 接口描述:?判断key对应的Hash类型元素是否存在某一field,返回1代表存在,返回0代表不存在。
2.5 HDELHDEL?接口定义: HDEL?key "filed1" ["field2","field3" ...] 接口描述:删除key对应的Hash类型元素一个或多个field值,返回实际被删除的field个数。
2.6 HLENHLEN?接口定义:HLEN?key 接口描述:?获得key对应的Hash类型元素当前存在的field的数量。
2.7?hash类型其它常用命令hash类型的常用还有诸如HKEYS(获得对应hash元素的所有field的值),HVALS(获得对应hash元素的所有field的value值),HINCRBY(使对应hash元素的某一field的value值增加),HDECRBY(使对应hash元素的某一field的value值减少)等等。 3.List?列表类型 常用命令3.1?LPUSH RPUSHLPUSH 接口定义:LPUSH?key "value1" ["value2","value3" ...] 接口描述:在对应key的列表元素头部(left 左侧)依次插入一个或多个数据节点,返回最终的列表长度。 RPUSH?接口定义 :RPUSH?key?"value1" ["value2","value3" ...] 接口描述:在对应key的列表元素尾部(right 右侧)依次插入一个或多个数据节点,返回最终的列表长度。
3.2 LPOP RPOP? LPOP?接口定义:LPOP?key? ?接口描述:返回对应key的列表元素头部(left 左侧)弹出(获得元素,并且从列表中移除)第一个数据节点。 ?RPOP?接口定义:RPOP?key? ?接口描述:返回对应key的列表元素尾部(right 右侧)弹出(获得元素,并且从列表中移除)第一个数据节点。
3.3 LLENLLEN 接口定义:LLEN?key 接口描述:返回对应key的列表元素拥有的数据节点个数
3.4 LRANGE?LRANGE 接口定义:LRANGE?key "start" "stop" 接口描述:返回对应key的列表元素?从start->stop下标之间的所有数据节点(和python一样,支持负数下标(从末尾开始计算))。
3.5 LREMLREM 接口定义:LREM key "count" "value" 接口描述:对应key的列表元素删除(count个)值为value的数据节点。 ? ??潜规则:当count > 0时,从左到右匹配和删除,count < 0时,从右到左匹配和删除,count = 0时,删除全部匹配的数据节点。
3.6 LINDEXLINDEX 接口定义:LINDEX?key "index" 接口描述:返回对应key的列表元素第index个数据节点,支持负数下标(从末尾开始计算)。
3.7 LSETLSET?接口定义:LSET key "index" "value" 接口描述:将对应key的列表元素中位于index下标位置的数据赋值为value(如果下标越界,会抛出异常)。
? 3.8?list列表类型其它常用命令list类型的常用还有诸如LTRIM(截取列表),LINSERT(向列表指定下标位置插入数据),RPOPLPUSH(将数据节点从一个列表转移到另一个列表)等等。 4.set集合类型?常用命令4.1 SADD SREMSADD?接口定义:SADD?key "member1" ["member2","member3" ...] 接口描述:?在对应key的集合元素中插入一到多个数据,返回实际被插入的数据个数(已经存在的数据不会被重复插入)。 SREM?接口定义:SREM?key?"member1" ["member2","member3" ...] 接口描述:?在对应key的集合元素中移除一到多个数据,返回实际被删除的数据个数(不存在的数据不会被计算)。
4.2 SMEMBERSSMEMBERS?接口定义:SMEMBERS?key 接口描述:返回key对应的集合元素中所有数据。
4.3 SISMEMBERSISMEMBER?接口定义:SISMEMBER?key "member" 接口描述:判断member是否存在于key对应的集合元素中,如果存在返回 1,如不存在返回 0。
4.4? SINTER SUNION?SDIFF?SINTER?接口定义:SINTER "key1" ["key2","key3" ...] 接口描述:获得一个或多个集合的交集。 SUNION 接口定义:SUNION?"key1" ["key2","key3" ...] 接口描述:获得一个或多个集合的并集。 SDIFF 接口定义:SDIFF?"key1" ["key2","key3" ...] 接口描述:获得一个或多个集合的差集,多个集合从左到右,进行运算。
4.5 SCARDSCARD?接口描述:SCARD?key 接口描述:?返回key对应的集合元素中数据的个数。
4.6?set类型其它常用命令set类型的常用命令还有诸如SINTERSTORE,SUNIONSTORE,SDIFFSTORE(取得交集、并集、差集的结果,同时保存为另一个集合),SRANDERMEMBER(从集合中随机获得元素),SPOP(从集合中随机弹出元素)等等。 5.sorted?set有序集合类型?常用命令5.1 ZADD ZREMZADD 接口定义:ZADD?key "score1" "member1" ["score2","member2","score3","member3" ...] 接口描述:在key对应的有序集合中插入一到多个?score->member?键值对,返回实际插入的数据(已经存在的数据不会被重复插入)。 ZREM?接口定义:ZREM?key?"member1" ["member2","member3" ...] 接口描述:在key对应的有序集合中删除一到多个数据,返回实际被删除的数据个数(不存在的数据不会被计算)。 ? 5.2? ZSCOREZSCORE 接口定义:ZSCORE key member 接口描述:返回key对应的有序集合某一member对应score的值。 5.3 ZRANGE ZREVRANGE?ZRANGE 接口定义:ZRANGE key start stop 接口描述:key对应的有序集合按照score从小到大的顺序,返回索引在start和stop之间的数据。 ZREVRANGE 接口定义:ZREVRANGE?key start stop 接口描述:key对应的有序集合按照score从大到小的顺序,返回索引在start和stop之间的数据。
5.4 ZINCRBYZINCRBY?接口定义:ZINCRBY?key "increment" "member" 接口描述:key对应的有序集合的某一个member增加"incrment"(可以为负数),并且返回执行完毕的结果。
5.5 ZCARDZCARD 接口定义:ZCARD key 接口描述:返回key对应的有序集合中数据的数量。
5.6?zset类型其它常用命令zset类型的常用命令还包括ZRANGEBYSCORE,?ZREVRANGEBYSCORE(按照score范围来进行顺序查找)、ZREM(移除集合内数据)等等。 6.?redis数据结构相关常用命令总结redis的数据结构相关命令还有很多,限于篇幅,上面只是简要描述了个人认为比较常用的命令。要想更加深入的理解这一部分内容,还是应该从官方文档,教学书籍入手,反复的尝试练习并且在工作中将其实践。 redis的设计是很优雅的,命令接口大多是正交的,使用者可以很直观的从命令的名称、参数定义,快速的理解命令的使用方法。但是,我认为例如SRANDERMEMBER,SREM等命令设计的过于灵活,同一参数可以因为处于不同数据范围而导致接口的行为完全不同,使得使用者被迫需要记住接口的一套独有规则。这时不如设计多个不同的简单接口分开实现功能来的简单直接。毕竟,有时过于简单反而会导致不必要的复杂性。 ? ?
?
? ? ?
?
? ? ? ?
? ?
? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |