虽然我们平时学的都是关系型数据库,但是像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