本文是对nosql的发展以及redis的概述,介绍了redis的String、List、Set、Hash、Zset5种常用数据类型,以及3种可以使用redis进行存储Geo、hyperloglog、bigmap等重要的数据类型
一、概述
Redis是一种非关系型数据库,由C++编写,单线程,支持网络(可以通过http协议去传输数据)、key/value数据库,基于内存存储可持久化的(如何持久化?RDB、AOF),数据结构存储系统。
1.1非关系型数据库的发展
网站的瓶颈:
1、大数据时代,海量数据的存储和读取更加高效快捷
2、MySql不能满足现状,Mysql数据库单表超过300万条就需要建立索引,不建立索引会变得非常慢(mySql底层索引是利用B+ 树)
3、读写混合,服务器无法承受
↓
传统的方式无法满足需求,mysql将缓存结合并搭建集群,使得数据库性能更好
缓存+MySQL+垂直拆分(读写分离)
↓
进一步更新,数据库分库分表+水平拆分(mysql集群)
↓
MySql等关系型数据库不够用了,数据量大,变化很快
有的使用存储一些比较大的数据,这样就会降低效率,如果有一种数据库专门来处理这种数据,mySql压力就会变小,大数据的IO压力下,表的结构是无法更改的(例如现在表中有一亿条数据,加列 就会出现问题)
1.2非关系型数据库诞生
1.2.1NOSQL的特点:
1、方便扩展(数据库之间没有关系,很好扩展)
2、大数据量的高性能,读写快,每秒读11万,写8万,NoSQL的缓存记录是一钟细粒度的缓存,性能高
3、数据类型是多样型的(不需要事先设计数据库,随取随用,如果是数据量十分大的表)
4、NoSql没有固定的查询语句,键值对存储,高性能、高可用、高可扩展性、CAP 定理和BASE(异地多活)、最终一致性
1.2.2NoSql的四大分类:
KV键值对:Redis、Tair、Memecache
文档型数据库:(Bson格式 和 json格式一样)mongodb
列存储数据库:HBase、分布式文件系统
图关系数据库:不是存图片的,是存关系的
1.2.3Redis的基础知识:
1、redis默认有16个数据库
2、Redis是单线程的还是多线程
原因:redis是基于内存操作,CPU不会影响redis的性能,redis的性能是根据机器的内存以及网络的带宽所决定的,既然可以用单线程来实现,那就使用单线程使用了(官方表示)
3、Redis为什么那么快?
原因:误区1:高性能一定意味着多线程;误区2:多线程一定比单线程效率高。核心原因:redis是将所有的数据都放到内存种的,多线程操作的时候CPU会做上下文切换的操作,对于内存来讲,没有上下文操作的就是效率最高的!在内存中,单线程就是效率最高的
二、Redis中八种数据类型:
2.1五种基本数据类型:
String、List、Set、Hash、Zset五种是经常使用的类型,其中String是使用的最多的
2.1.1String类型常用操作命令(Linux中):
redis中16个数据库,不指定数据库,默认操作第一个数据库
set key value:设置值
get key:获取值
incr key :自增1
decr key:自减1
incrby key n:指定步长自增(n为步长)
decrby key n:指定步长自减(n为步长)
getrange key n m :截取字符串[n,m] 将字符串中第n位和第m位截取
getrange key 0 -1:查看字符串 效果等用于 get key
setrange key n xx :替换第n位开始的字符串为xx
setex key n value:设置key 的值为 value,n秒后过期(在分布式锁中常常使用)
ttl key:查看key的剩余时效
setnx key value:如果key不存在,创建key值为value;如果key存在,则创建失败
mset key1 value1 key2 value2 key3 value3:批量设置多个值
mget key1 key2 key3:多次获得多个值
msetnx key1 value1 key2 value2:msetnx是一个原子性的操作,要么一起成功,要么一起失败
getset key value:先get在set,如果存在值,获取之前的值,并设置新的值
应用场景:String 是redis中使用最多的类型,可以用来做计数器、统计数量、缓存以及对象存储(可以存储对象,但是用hash会更加方便)
2.1.2 List类型的常用操作命令(Linux):
lpush list名 value:在list的左边key键中添加value值
rpush list名 value:在list的右边添加key,value
lpop list名 :移除list中左面的键
rpop list名 :移除list中右面的键
lrem list名 n key :移除list集合中指定个数的value(n为数量)
lrange list名 0 -1:获取list中的值
ltrim list名 n m:截取list中指定的长度[n,m]
exists list名:判断这个list是否存在
linsert list名 befroe/after value :将某个具体的value值插到某个元素的前或后
总结:实际上就是一个链表,在节点的前面、后面都可以去插入值
应用场景:消息队列(LPUSH、RPUSH),栈(LPUSH、LPOP)
2.1.3 Set类型的常用操作命令(Linux):
Set的值是不可以重复的,无序的
sadd set集合名 value:添加值
smembers set集合名:查看所有成员
sismember set集合名 value:查看具体元素的成员是否存在
scard set集合名:获取set集合元素的个数
srem set集合名 具体元素:删除某个值
srandmember set集合名 n:获取n个随机的值
stop set集合名 key:删除具体key的值
smove set集合名1 set集合名2 value:将指定的值移动到另一个中
sdiff set集合名1 set集合名2 :取两个set集合中的差集
sinter set集合名1 set集合名2:取两个set集合中的交集
sunion set集合名1 set集合名2:并集
应用场景:共同关注、共同好友等
2.1.4 Hash类型的常用操作命令(Linux):
相当于是一个key-map的map集合
hset hash名 字段 值:设置值
hset hash名:取值
hdel hash名 字段:删除
hlen hash名:hash的长度
hextists hash名 字段名:判断某个字段是否存在
hkey hash名:获取hash中所有的字段
hvals hash名:获取hash中的所有值
Hincrby hash名 字段 值:字段增加指定值
hinrcby hash名字段 -值:字段减少指定值:
hsetnx hash名 字段 value:不存在则设置值、存在则不能设置(分布式锁中使用)
hash的应用场景:存储对象,变更数据的保存,比String更适合存储对象
2.1.5 Zset类型的常用操作命令(Linux):
在set的基础上增加了一个值,增加了一个score作为排序的标识
Set | K1,v1 |
Zset | K1,v1,score1 |
zadd zset名 key value:添加值
zadd zset名 key value key2 value2:添加多个值
zrange zset名 0 -1:查看所有值
zrangebyscore zset名 min max:从小到大(可以取-inf、+inf)
zrevrange salary 0 -1:从大到小
zrem zset名 key:移除
zcard zset名 :查看长度
应用场景:set排序、存储班级成绩表、工资表排序,普通消息:重要消息,带权重进行判断;排行榜应用 top
2.2三种基本数据类型:
2.2.1geospatial地理位置
可以存储地理信息,经度和维度
添加地址信息 :Getadd 键名 经度 维度 城市名
获取指定城市的经度和纬度:Getpos 键名 城市名 (获得的是经度和维度)
两人之间的距离:Geodist 键名 城市名 城市名 单位(km、m):可获得两个城市之间的距离
我附近的人:以给定的经度纬度为中心,找出某一半径的人或城市
Georadius 键名 经度 维度 半径 单位:获得在当前 经度 和 维度 范围内的城市
Georadius 键名 经度 维度 半径 单位 withdist:获得当前 经度 维度 半径范围内的城市的直线距离
Georadius 键名 经度 维度 半径 单位 withcoord : 获得当前 经度 纬度 半径 范围内的城市的经纬度地址
Georadius 键名 经度 维度 半径 单位 withcoord count :指定数量
GEO的底层实现原理:
是zset的有序集合,可以利用查看zset的方式去查看geo的所有数据,geo是没有删除的命令的,可以用zeset的删除命令去删除geo中的地址信息
2.2.2Hyperloglog:(基数计数,内部是由算法和Bigmap实现的)
网页的UV(访问量)一个人访问一个网站多次,也算是一个人访问,传统的方式,set保存用户id,然后就可以统计set中元素数量作为标准判断!这个方式如果保存大量的用户id,就会比较麻烦!(用户数量太大,保存了大量的用户id,目的是为了保存用户访问的数量)
Redis hyperloglog的优点:占用的内存是固定的,2^64不同的元素的技术,只需要12kb内存,但是会存在0.81%的错误率,但是在统计任务中可以忽略不计
添加数据:
Pfadd 键名 数据1 数据2 :向指定的键中添加元素
Pfcount 键名 :获取指定键的数据的长度
Pfmerge 键名3 键名2 键名1 : 将键名2和键名1的元素合并到键名3中 数据取并集
应用场景:网站访问数量统计,允许容错则可以使用会有0.81%的容错率,不允许容错则不能使用
2.2.3Bigmap:
(可以理解为通过一个bit数组来存储特定数据的一种数据结构)
位存储,通过位运算来表示元素对应的值
统计用户信息,活跃,不活跃,登录,不登录,365打卡,两个状态的,都可以使用Bigmaps
Bigmaps位图,数据结构,都是操作二进制位来进行记录,就只有0和1两个状态!
常用命令:
存储数据:Setbit key 第几个(作为标识) 值
获取值:getbit key 周几
获取某个状态的值:bigcount sign:统计打卡的天数
应用场景:统计海量数据的两种状态,例如上班的打卡状态等