1.nosql数据库概述
1.1什么是nosql
- nosql,not only sql的缩写,指的是非关系型数据库,是对不同于传统关系数据库的统称。
1.2nosql使用场景
-
主要用于超大规模的数据存储,这类数据的存储不需要固定的数据模式,不需要复杂的查询关系,主要诉求是快速存储,快速横向扩展。
-
对数据库高并发的读写需求
-
对数据库高可拓展性的需求,传统数据据很难横向扩展,要做数据迁移甚至需要停机维护。而nosql横向拓展简单,而且很多还支持分布式技术。
1.3nosql分类
-
key-value键值对存储数据库
-
redis,mencacheDB
-
key不允许重复,可以通过key快速查询value,不需要考虑value的格式
-
-
文档存储数据库
-
mongodb、couchdb
-
文档数据库用类似json的格式存储,存储的内容是文档型的。
-
-
列存储数据库
-
hbase
-
按列存储最大的特点是方便存储结构化的数据,方便对数据做压缩,尤其是对列的查询效率很高。
-
-
图关系存储数据库
-
neo4J
-
一种以图结构存储的数据库,里面包括了点(实体)和边(关系),这类数据库尤其适合做复杂关系的查询。
-
2.redis概述
- redis是一个高性能的key-value数据库,是为了解决高并发、高扩展、大数据存储问题产生的解决方案。
2.1redis使用场景
-
缓存技术:将数据挪到操作更快的地方临时存储起来,以便使用的时候可以快速拿到,而不需要去数据库中查询,缓存指的就是内存。
-
数据写入:直接写在硬盘的数据库中
-
数据查询:先去内存中的redis查,内容如果没有这个数据,再去数据库中查。
-
适用于高并发,尤其是读多写少的情况。
-
-
redis不能单独使用,它要配合关系型数据库一起用。redis相当于一个中间件,它介于用户服务和数据库服务之间,用来减轻对后端数据库的压力。
-
比如说,一个查询接口,第一次查询要从数据库查询,查完之后就会被redis放入缓存中,这样第二次查就可以不走数据库了,直接从缓存中拿数据就行了。
-
一般我们会把频繁使用的、需要耗时长才能查到的数据,放到缓存中。
2.2redis的优势
-
读写速度很快,因为数据在内存中。但缺点是数据没办法持久化保存,关机重启断电都会导致内存数据丢失。
-
高并发的优势,可以大大减轻后台数据库的压力。否则高并发的查询需求对传统的数据库和硬盘读写来说,都是很大的压力。
2.3.redis缓存策略
-
旁路缓存
- 用的最多的,适合读多写少的场景。这种策略下,redis要同时维护数据库和缓存,使之保持同步。它是以后台数据库为准。
-
读写穿透
- 用的很少,它把缓存当作主要数据存储,以缓存为主,读写都先写在缓存中,然后redis再把数据及时同步到数据库中,这个主要是减轻了应用程序的负担。
-
异步缓存
- 用的也不多,跟上面类似,也是以缓存为主,读写都先在缓存中,但数据之间的同步是采用异步的方式进行的,不是及时同步的,这时候的风险就是缓存的数据还没来得及跟数据库同步,遇到关机重启等异常导致缓存失效,数据就丢了。
2.4redis的安装
-
redis是在Linux服务器上来使用的,不建议在Windows上用,所以redis官网也没有提供Windows版本的redis,我们需要在github上下载微软官方提供的redis版本。为了学习方便,我们直接使用微软的这个版本。
-
安装的时候直接选用后缀是msi的图形化安装版本,下一步即可,注意勾选添加到环境变量选项,其他保持默认即可。
-
安装完成之后,直接找到安装目录,打开redis文件夹,就可以看到启动文件:
-
redis-server.exe :启动redis服务的可执行文件,双击。
-
redis-cli.exe:启动redis客户端的文件,双击。
-
默认redis不需要密码,可以直接连,如果需要设置密码,要修改配置文件redis.windows.conf
-
启动了服务和客户端后,可以通过客户端发送PING命令来测试是否连接成功,如果成功,会得到PONG的回复。
-
2.4redis使用的端口号是:6379
3.redis数据类型及操作命令
-
redis通用的操作
-
获取所有键:keys *
-
统计键key的总数:dbsize
-
判断某个key是否存在:exists key
-
删除某个key:del key
-
查询键的类型:type key
-
切换数据库:redis一共有16个数据库,编号分别是0-15,默认是0号库。select 数据库编号
-
移动键:move key 数据库编号
-
清空当前数据库:flushdb
-
清空所有数据库:flushall
-
-
redis的数据类型有:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)
3.1string
-
string类型是最基本的数据类型,string可以包含任何数据,甚至图片等序列化的数据。
-
添加或修改指定key的value值
-
语法:set 键值对,当key不存在的时候,会新建这条数据。key存在即是修改,会覆盖原来的value。
-
使用mset可以同时设置或修改多个键值对
-
举例:set zhangsan 23
-
举例:mset lisi 22 wangwu 20
-
-
查询指定key的value值
-
语法:get
-
举例:get lisi
-
-
删除指定的key的键值对
-
语法:del
-
举例:del wangwu
-
3.2hash
-
redis中的hash是一个string类型的字段(field)和值(value)的映射表,一个key对应多个field-value值。通过key和field一起来操作某个value。hash类型适合用于存储对象的数据。
-
添加或修改数据
-
语法:hset key field value
-
使用hmset可以同时修改多个值
-
举例:hset user01 username root
-
举例:hmset user02 username admin password 123456
-
-
查询指定field的值:
-
语法:hget hash field
-
举例: hget user02 password
-
-
查询所有的filed和value
-
语法:hgetall key
-
举例:hgetall user01
-
-
查询hash的字段数量
-
语法:hlen key
-
举例:hlen user01
-
-
查询所有的field或value
-
语法:hkeys key 或 hvals key
-
举例:hkeys user01
-
举例:hvals user01
-
-
删除hash的字段field
-
语法:hdel key field
-
举例:hdel user02 password
-
-
删除整个hash
-
语法:del hash
-
举例:del user01
-
3.3 list
-
list是字符串列表,按照插入顺序排序。
-
创建list:
-
语法:lpush 列表名称 值1 值2 …
-
举例:lpush city beijing shanghai guangzhou
-
-
添加数据:
-
从左侧添加:lpush city shenzhen
-
从右侧添加:rpush city xian
-
在某个值前面插入数据:linsert city before beijing chengdu
-
在某个值后面插入数据:linsert city after beijing wuhan
-
-
查询数据:
-
根据区间查询:lrange 列表 start_index end_index
-
举例:lrang city 0 2 获取了前三个值
-
举例:lrange city 0 -1 获取了所有值,-1代表最后一位
-
根据下标查询:lindex 列表 下标
-
举例:lindex city 3
-
获取列表长度:llen 列表
-
-
修改数据:
-
根据下标修改数据:lset 列表 下标 新数据
-
举例:lset city 0 hangzhou
-
-
删除数据:
-
删除最左边的元素:lpop city
-
删除最右边的元素:rpop city
-
删除指定值的元素:lrem 列表 num value,此处的num指定删除几个value,value有可能有重复,num是正数是代表从左边删,负数从右边开始删。0代表删除全部为value的数据
-
举例:给city再加一个wuhan,lpush city wuhan,从左往右删除第一个wuhan:lrem city 1 wuhan
-
3.4 set
-
set是一种无序的集合,且元素不能重复
-
添加值到集合:sadd 集合 值1 值2 …
- 举例:sadd zimu a b c d e
-
查询集合中的所有元素:smembers 集合
- 举例:smembers zimu
-
统计集合中所有元素的个数:scard 集合
- 举例:scard zimu
-
随机删除一个元素:spop 集合
- 举例:spop zimu
-
删除集合中某个元素:srem 集合 元素
- 举例:srem zimu a
-
集合之间操作:
-
交集:sinter 集合1 集合2
-
并集:sunion 集合1 集合2
-
差集:sdiff 集合1 集合2 在集合1中有的但是集合2中没有的元素
-
举例:再创建一个集合: sadd pinyin a b c d zh ch ang eng
-
3.5 zset
-
zset元素同样不能重复,但是有序,根据什么排序?根据一个分值。zset每个元素都会有一个分值,通过分值来升序排序,另外zset里面的第一个值可以用-inf来表示,+inf表示最后一个。
-
添加:zadd 有序集合 分值 元素值
- 举例:zadd stu 60 zhangsan 70 lisi 80 wangwu
-
查询:
-
根据索引查询(默认升序):zrange 有序集合 开始下标 结束下标 也可以附带分值(withscores)
- 举例: - zrange stu 0 -1 查询所有元素 - zrange stu 0 1 withscores 查询前两个元素,同时带分值显示
-
根据分值查询(升序排序):zrangebyscore 有序集合 开始分值 结束分值 也可以附带分值(withscores)
- 举例:zrangebyscore stu 60 70 查询60-70分值的元素 - 举例: zrangebyscore stu -inf +inf 查询所有的 - 举例:zrangebyscore stu -inf 70 查询第一个到70的元素 - zrangebyscore stu -inf 70 withscores 查询结果带分数
-
反转顺序:zrevrange 有序集合 起始下标 结束下标
- 举例:zrevrange stu 0 -1 -
统计zset元素个数:zcard 有序集合
-
-
举例:zrangebyscore stu 60 70 查询60-70分值的元素
- 举例: zrangebyscore stu -inf +inf 查询所有的 - 举例:zrangebyscore stu -inf 70 查询第一个到70的元素 - zrangebyscore stu -inf 70 withscores 查询结果带分数
-
反转顺序:zrevrange 有序集合 起始下标 结束下标
- 举例:zrevrange stu 0 -1 -
统计zset元素个数:zcard 有序集合
-
删除:zrem 有序集合 元素值
-