一、NoSQL概述
1.1、NoSQL
NoSQL = Not Only SQL(不仅仅是SQL)
Not Only Structured Query Language
NoSQL泛指非关系型数据库,随着web2.0互联网的诞生,传统的关系型数据库很难对付web2.0时代!尤其是超大规模的高并发的社区,暴露出来很多难以克服的问题,NoSQL在当今大数据环境下发展的十分迅速,Redis是发展最快的。
- 关系型数据库:列+行,同一个表下数据的结构是一样的。
- 非关系型数据库:数据存储没有固定的格式,并且可以进行横向扩展。
特点
-
方便扩展(数据之间没有关系,很好扩展!)
-
大数据量高性能(Redis一秒可以写8万次,读11万次,NoSQL的缓存记录级,是一种细粒度的缓存,性能会比较高!)
-
数据类型是多样型的!(不需要事先设计数据库,随取随用)
-
传统的 RDBMS 和 NoSQL
传统的 RDBMS(关系型数据库) - 结构化组织 - SQL - 数据和关系都存在单独的表中 row col - 操作,数据定义语言 - 严格的一致性 - 基础的事务 - ...
Nosql - 不仅仅是数据 - 没有固定的查询语言 - 键值对存储,列存储,文档存储,图形数据库(社交关系) - 最终一致性 - CAP定理和BASE - 高性能,高可用,高扩展 - ...
真正在公司中的实践:NoSQL + RDBMS 一起使用才是最强的。
为什么要用NoSQL ?
- 用户的个人信息,社交网络,地理位置。用户自己产生的数据,用户日志等等爆发式增长!
这时候我们就需要使用NoSQL数据库的,Nosql可以很好的处理以上的情况!
1.2、Nosql的四大分类
-
KV键值对
- 新浪:Redis
- 美团:Redis + Tair
- 阿里、百度:Redis + Memcache
-
文档型数据库
- MongoDB(掌握)
- 基于分布式文件存储的数据库。C++编写,用于处理大量文档。
- MongoDB是RDBMS和NoSQL的中间产品。MongoDB是非关系型数据库中功能最丰富的,NoSQL中最像关系型数据库的数据库。
- ConthDB
- MongoDB(掌握)
-
列存储数据库
- HBase(大数据必学)
- 分布式文件系统
-
图关系数据库(用于广告推荐,社交网络)
- Neo4j
- InfoGrid
分类 | Examples举例 | 典型应用场景 | 数据模型 | 优点 | 缺点 |
---|---|---|---|---|---|
键值对 | Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB | 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。 | Key 指向 Value 的键值对,通常用hash table来实现 | 查找速度快 | 数据无结构化,通常只被当作字符串或者二进制数据 |
列存储数据库 | Cassandra, HBase, Riak | 分布式的文件系统 | 以列簇式存储,将同一列数据存在一起 | 查找速度快,可扩展性强,更容易进行分布式扩展 | 功能相对局限 |
文档型数据库 | CouchDB, MongoDb | Web应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容) | Key-Value对应的键值对,Value为结构化数据 | 数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构 | 查询性能不高,而且缺乏统一的查询语法。 |
图形数据库 | Neo4J, InfoGrid, Infinite Graph | 社交网络,推荐系统等。专注于构建关系图谱 | 图结构 | 利用图结构相关算法。比如最短路径寻址,N度关系查找等 | 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群 |
二、Redis入门
2.1、概述
Redis(Remote Dictionary Server ),即远程字典服务。
是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
作用
- 内存存储、持久化,内存是断电即失的,所以需要持久化(RDB、AOF)
- 高效率、用于高速缓冲
- 发布订阅系统
- 地图信息分析
- 计时器、计数器(eg:浏览量)
- 。。。
特性
- 多样的数据类型
- 持久化
- 集群
- 事务
- 。。。
2.2、Windows搭建
- 下载网址:https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100
- 解压
- 开启redis-server.exe
- 启动redis-cli.exe测试
- 在redis-cli.exe输入ping测试能否成功,响应PONG即可成功
- 存值:set key value
- 取值:get key
3.3、Linux搭建
-
下载网址:https://pan.baidu.com/share/init?surl=2NnJVizIpnF25vkT2zgKSA(提取码:balm)
-
解压Redis的安装包!程序一般放在 /opt 目录下
-
基本插件安装
yum install gcc-c++ # 然后进入redis目录下执行 make # 然后执行 make install
-
redis默认安装路径 /usr/local/bin
-
/usr/local/bin下创建kconfig
#在/usr/local/bin下 mkdir kconfig
-
将/opt下redis的配置文件redis.conf复制到目录 /usr/local/bin/kconfig下
#在/usr/local/bin下 cp /opt/redis-5.0.7/redis.conf kconfig
-
redis默认不是后台启动的,需要修改配置文件
#在/usr/local/bin/kconfig下 vim redis.conf # i:进入修改操作 # esc:退出修改操作 # :wq:退出浏览界面
-
通过指定的配置文件启动redis服务
#在/usr/local/bin下 redis-server kconfig/redis.conf
-
使用redis-cli连接指定的端口号测试,Redis的默认端口6379
redis-cli -p 6379
-
ping可以响应pong即可成功
-
查看redis进程是否开启
#在/usr/local/bin下 ps -ef|grep redis
-
关闭redis服务
shutdown
3.4、性能测试工具
**redis-benchmark:**Redis官方提供的性能测试工具
测试
# 测试:100个并发连接 100000请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
3.5、基础知识
Redis是将所有的数据放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换:耗时的操作!),对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都是在一个CPU上的,在内存存储数据情况下,单线程就是最佳的方案。
- redis默认有16个数据库
- redis是单进程的
- redis是基于内存操作的
- 高性能的服务器不一定是多进程的
命令介绍
select db #进入指定的数据库
dbsize #查看数据库的数据有多少条
keys * #列出数据库所有数据
flushdb #删除当前数据库数据
flushall #删除所有数据库数据
6379端口的由来
- 6379在是手机按键上MERZ对应的号码,而MERZ取自意大利歌女AlessiaMerz的名字。
三、五大数据类型
Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。
3.1、Rediskey基本命令
-
exists key:判断键是否存在
-
del key:删除键值对
-
move key db:将键值对移动到指定数据库
-
expire key second:设置键值对的过期时间
-
type key:查看value的数据类型
-
ttl key:返回key的过期时间
- 当前key没有设置过期时间,所以会返回-1.
- 当前key有设置过期时间,而且key已经过期,所以会返回-2.
- 当前key有设置过期时间,且key还没有过期,故会返回key的正常剩余时间.
-
rename key newkey:修改key的名字
-
renamenx key newkey:当 newkey 不存在时,将 key 改名为 newkey
3.2、String(字符串)
APPEND key value #向指定key的value后面追加字符串
DECR/INCR key #将指定key的value数值进行+1/-1(仅对于数字)
INCRBY/DECRBY key n #对指定的key增加/删减指定的步长
STRLEN key #获取key的value字符串长度
GETRANGE key start end #获取key的指定位置的value
SETRANGE key offset value #用指定的value替换key中offset开始的值(offset是数值)
GETSET key value #将key的值设为value,并返回key的旧值
SETNX key value #仅当key不存在时进行set
MSET k1 v1 k2 v2 #批量set键值对
MSETNX k1 v1 k2 v2 #批量set键值对,仅当参数中所有的key都不存在时执行(原子性,要么一起成功要么一起失败)
MGET k1 v1 k2 v2 #批量获取key的value
3.3、List(列表)
#L代表左,R代表右
#喝了就吐代表栈,吃了就拉代表队列
#list中允许value重复
LPUSH/RPUSH key value1 value2 #从左边/右边向列表添加一个或多个值
LRANGE key start end #获取list起止元素
LPUSHX/RPUSHX key value1 value2 #向已存在的列表中push一个或多个值
LLEN key #查看列表长度
LINDEX key index #通过索引获取列表元素
LSET key index value #通过索引为元素设值
LPOP/RPOP key #从左边/右边移除值并返回
RPOPLPUSH source destination #将列表的尾部(右)最后一个值弹出并返回,然后加到另一个列表的头部
LTRIM key start end #通过下标截取指定范围内的列表(修改原列表)
LREM key count value #count>0:从头部开始搜索,然后删除指定的value,至多删除count个
#count<0:从尾部开始搜索,然后删除指定的value,至多删除count个
#count=0:删除列表中所有指定的value
BLPOP/BRPOP key1 key2 timout #移除并获取列表第一个/最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
BRPOPLPUSH source destination timeout #和RPOPLPUSH source destination功能相同,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
3.4、Set(集合)
sadd key member1 member2 #向集合中无序添加一个/多个成员
scard key #获取集合的成员素
smembers key #返回集合中所有的成员
sismember key member #查询member元素是否是集合的成员,结果是无序的
srandmember key [count] #随机返回集合中count个成员,count缺省值为1
spop key [count] #随机移除并返回集合中count个成员,count缺省值为1
smove source destination member #将source集合的成员member移动到destination集合
srem key member1 member2 #移除集合中一个/多个成员
sinter key1 key2 #返回所有集合的交集
sinterstore destination key1 key2 #在sinter的基础上,存储结果到集合中,覆盖
sunion key1 key2 #返回所有集合的并集
sunionstore destination key1 key2 #在sunion的基础上,存储结果到集合中,覆盖
3.5、Hash(哈希)
hset key field value #将哈希表 key 中的字段 field 的值设为 value。重复设置同一个field会覆盖,返回0
hmset key field1 value1 field2 value2 #同时将多个 field-value (域-值)对设置到哈希表 key 中。
hsetnx key field value #只有在字段field不存在时,设置哈希表字段的值
hexists key field #查看哈希表key中,指定的字段是否存在
hget key field value #获取存储在哈希表中指定字段的值
hmget key field1 field2 #获取所有给定字段的值
hgetall key #获取在哈希表key的所有字段和值
hkeys key #获取哈希表key中的所有字段
hlen key #获取哈希表中字段的数量
hvals key #获取哈希表中所有值
hdel key field2 field2 #删除哈希表中一个/多个field字段
3.6、Zset(有序集合)
zadd key score1 member1 score2 member2 #向有序集合添加一个或多个成员,或者更新已存在成员的分数
zcard key #获取有序集合的成员数
zcount key min max #计算在有序集合中指定区间score的成员数
zincrby key n member #有序集合中对指定成员的分数加上增量n
zscore key member #返回有序集中,成员的分数值
zrank key member #返回有序集合中指定成员的索引
zrange key start end #通过索引区间返回有序集合指定区间内的成员
zrangebyscore key min max #通过分数返回有序集合指定区间内的成员==-inf 和 +inf分别表示最小最大值,只支持开区间()==
zrem key member1 member2 #移除有序集合中一个/多个成员
zrevrange key start end #返回有序集中指定区间内的成员,通过索引,分数从高到底
四、三种特殊数据类型
4.1、Geospatial地理位置
- 有效的经度从-180度到180度。
- 有效的纬度从-85.05112878度到85.05112878度
geoadd china:city 114.878872 30.459422 beijing #添加地理位置,参数 key 经度 维度 名称
geoadd china:city 116.413384 39.910925 guangzhou 79.920212 37.118336 hetian #添加多地
geopos china:city beijing #获取某地的经纬度
geopos china:city shanghai beijing #获取多地的经纬度
geodist china:city shanghai beijing #计算距离
geodist china:city shanghai beijing km #计算距离为千米
georadius china:city 118 30 500 km #查找以经纬度118 30 为圆心,500km为半径的城市
georadius china:city 119 30 200 km withdist #查找并带上距离
georadius china:city 119 30 200 km withcoord #查找并带上经纬度坐标
georadius china:city 119 30 200 km withcoord withdist count 2 #查找并带上坐标距离、限定查找个数
georadiusbymember china:city guangzhou 100 km #查找成员为圆心的其他成员
geohash china:city guangzhou hetian #该命令返回11个字符的geohash字符串,将二维的经纬度转化为一维的字符串,字符串越接近则距离越接近
- Geo的底层实现原理是Zset,所以也可以Zset命令来操作Geo
zrange china:city 0 -1 #
zrem china:city shanghai #
4.2、Hyperloglog基数统计
基数:数据集中不重复的元素的个数
#比如一个网站登录人数,一个人每次登录往myset存入a,那么重复登录就会有多个a,在pfcount计数的时候会排除相同的值
pfadd myset a b c d e f g h i j #添加
pfadd myset2 i j k c v z h
pfcount myset #计数,不重复
pfmerge myset3 myset myset2 #合并集合myset myset2 到 myset3
- 如果允许容错,那么可以使用Hyperloglog !
- 如果不允许容错,就使用set或者自己的数据类型即可 !