Redis学习笔记一:常用数据结构及其命令

虽然我们平时学的都是关系型数据库,但是像Redis这样的Nosql在实际开发中也用得非常多啦。不可避免的,我们应该学习一下Redis。

这是Redis第一篇的学习笔记,主要记录redis的数据类型以及常用命令。

基础知识

NoSQL:即 Not-Only SQL( 泛指非关系型的数据库),作为关系型数据库的补充。

Nosql相比关系型数据库是怎样更好地解决海量用户和高并发的问题的呢?有两点:

①降低磁盘IO次数,越低越好 —— 内存存储
②去除数据间关系,越简单越好 —— 不存储关系,仅存储数据
那么Redis就是其中一个著名的Nosql啦。

Redis (REmote DIctionary Server) 是用 C 语言开发的一个开源的高性能键值对(key-value)数据库。

Redis的一些特征:
1. 数据间没有必然的关联关系
2. 内部采用单线程机制进行工作
3. 高性能。官方提供测试数据,50个并发执行100000 个请求,读的速度是110000 次/s,写的速度是81000次/s。
4. 多数据类型支持
   字符串类型 string
   列表类型 list
   散列类型 hash
   集合类型 set
   有序集合类型 sorted_set
4. 持久化支持。可以进行数据灾难恢复

Redis的数据结构

Redis支持的且我们常用的数据有5个:String,Hash,List,Set,Sortset 。五个数据结构各有特点,我们应当熟悉它们,然后在实际的场景/业务中选择最合适的数据结构。

在这之前要先提到的一点:上诉的数据结构指的是(Key,Value)键值对中value的数据结构,而Key它永远是String类型的。

String

string类型是最简单的,即 (key,value)是简单的 (string,string) 键值对。

增删改查命令:

增加一条记录(key,value):set key value
查找key的记录:get key
删除key的记录:del key
增加多条记录:mset key value [key1 value1]
查找多个key的记录:mget key [key1]

其他命令:

strlen key   //获取字符串长度
append key value   //如果原始信息存在就追加,否则新建
setnx key value    //不存在就设置,存在就不设置
incr key     //使key的value加一
incrby key num   //给key的值增加num(int 类型),num 正数则为加,num 为负数 则为减
incrbyfloat key num   //给key的值增加num(float 类型)
decr key     //使key的value减一
decrby key num     //给key的值减num
setex key second value     //设置key的值为value存活时间为second秒(注意是value)
psetex key millisecond value   //设置key的值为value存活时间为millisecond毫秒(注意是value)


注意事项:

①数据未获取到  (nil)等同于null

②数据最大存储量  512MB

③数值计算最大范围(java中的long的最大值)  9223372036854775807

Hash
hash比较有意思,它是 (key, field, value) 的三元对,key还是跟其他类型一样的key,但是一个key之下又可以拥有多个 (field, value) 键值对。值得注意的是这里的value才是值,field不是我们说的值。

hash类型:底层使用哈希表结构实现数据存储。

增删查改

增加一条(key field value)记录:hset key field value
查找一条(key field)记录:hget key field
删除(key field)这条记录:hdel key field
增加多条(key fieldx valuex)记录:hmset key field value [field1 value2]
查找多条(key fieldx)记录:hmget key field [field1]

其他命令

hgetall key   //获取key的全部的值,即所有的(field, value)对
hlen key   //获取key的值的数量,即有多少对(field, value)
hexists key field   //key是否存在这个field
hkeys key   //这个key的所有field
hvals key   //这个key的所有值
hincrby key field num   //给key的field的value增加num (num 为int值)
hincrybyfloat key field num   //给key的field的value增加num (num 为float)
hsetnx key field value   //存在不设置,不存在设置

注意事项

①hash类型下的value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到,对应的值为(nil)

②每个 hash 可以存储 2^32 - 1 个键值对

List
人如其名,就是链表,list的底层使用双向链表存储结构实现。所以其实就是一个key对应的value是一个双向链表。并且需要注意的一点list是有左右顺序的,插入数据和查找数据都要指定左/右顺序,这点需要细细体会。

增删改查

lpush key value [value1]   //从左边添加
rpush key value [value1]   //从右边添加
lrange key start stop    //从左边开始获取start到stop的value
lindex key index      //从左边开始数获取第index个value
llen key      //长度
lpop key   //就是左边pop操作
rpop key   //就是右边pop操作

其他命令

规定时间内获取并移除数据,跟上面相比就是多了个时间
blpop key1 [key2] timeout
brpop key1 [key2] timeout
brpoplpush source destination timeout

lrem key count value    //移除指定数据 ,左边数起来第

注意事项

①list中保存的数据都是string类型的,数据总容量是有限的,最多2^32 - 1 个元素 (4294967295)。
②list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作
③获取全部数据操作结束索引设置为-1
④list可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载

Set

set就像是C++的set,Java的Hashset一样。就是一个key对应一个集合。

增删改查

增加记录:sadd key member [member1]
查找一个key对应的集合:smembers key
删除一个key的set中的一些值:srem key member [member1]
获取总量:scard key
判定是否存在这个键值对:sismember key member
随机获取(原集合保留,即原元素不会减少):srandmember key [count]
随机获取(原集合不保留,即原元素会减少):spop key

集合操作

集合交集:sinter key key1 key2
集合并集:sunion key key1 key2
集合差集:sdiff key key1 key2

以下显然destination是目标集合

存储集合交集:sinterstore destination key key1 key2
存储集合并集:sunionstore destination key key1 key2
存储集合差集:sdiffstore destination key key1 key2
将指定数据从原始集合中移动到目标集合中:smove source destination member

注意事项

① set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份
② set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间


Sorted_Set

看到上面的set非常好用,但是如果我们即像用一个key对应一个set,但是又像对这个set进行排序怎么办?于是sorted_set应运而生,与set不同的就是sorted_set中set元素需要指定一个score,redis将使用这个score对set中的值进行排序。

增删改查

增加记录,注意需要指定score,即(score,member)为一对:zadd key score member [score1 member1]
删除记录,指定key和member就行,不用score:zrem key member [member1]
获取全部(升序):zrange key start stop [withscores]
获取全部(降序):zrevrange key start stop [withscores]

注意下面两个的min max是score的区间,即score在[min,max]内的记录
按条件查(升序):zrangebyscore key min max [withscore limit]
按条件查(降序):zrevrangebyscore key max min [withscore limit]

按条件删除(索引):zremrangebyrank key start stop    //注意按索引
按条件删除(score):zremrangebyscore key min max    //注意按score

获取集合总量:zcard key | zcount key min max
存储集合交集: zinterstore destination numkeys key key1
存储集合并集:zunionstore destination numkeys key key1
获取索引(正序):zrank key member
获取索引(倒序):zrevrank key member
score值获取:zscore key member
score值修改:zincrby key num member

注意事项

① score保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992

② score保存的数据也可以是一个双精度的double值,基于双精度浮点数的特征,可能会丢失精度,使用时候要慎重

③ sorted_set 底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被反
复覆盖,保留最后一次修改的结果

Key通用操作

其实我们有一些对key通用的操作,即无论value是什么数据结构,key都可以这样操作。其实也很好理解,因为key一定是string类型的嘛。

删除key,那连带他的记录也没了:del key
判断一个key是否存在:exists key
获取key数据类型:type key

指定有效期:

expire key seconds    //秒
pexpire key milliseconds  //微秒
expireat key timestamp   //时间戳
pexpireat key milliseconds-timestamp

获取有效期:

ttl key      //(查询结果:不存在-2,存在且永久-1,存在有期限>=0
pttl key       // 与上诉对应的,是微秒

其他:

设置永久:persist key    //原本是有时限的,现在永久了
查询key:key pattern                           //pattern是匹配的式子取值*  ?  []等等,像正则表达式类似的     
重命名:rename key newkey    //直接重命名了,newkey本来有的,现在被覆盖了
    renamenx key newkey     //较之上面的改名,newkey有的话修改失败,更安全
对key排序:sort

数据库操作

选择数据库,有0-15个:select index
数据在数据库直接移动:move key db
数据库大小:dbsize

数据清除:  

①单库删除:flushdb   
②多库删除:flushall

 

Redis的指令也不少,比较难记住,记录在这里以后忘记了来查。OK,第一篇学习笔记就到这里了,Redis还有更多知识等着学习。

参考资料:

Bilibili黑马程序员的Redis视频:https://www.bilibili.com/video/BV1CJ411m7Gc

原文地址:https://www.cnblogs.com/clno1/p/12984606.html