NOSQL
数据库发展历史
访问量低:
App --> DAL(数据库访问层) --> Mysql实例
访问量提高: 读写分离
添加缓存 : 变数据的读取速度
进一步提高: 分库分表
为什么用NOSQL
NOSQL(Not Only SQL)泛指非关系型的数据库(没有 行,列 的概念 用 Map 替代)
处理 用户的个人信息,社交网络,地理位置. 用户自己生产的数据,用户日志等等的爆发式增长
总而言之,就是处理大量数据的读写问题
特点:
1. 数据之间没有关系,好扩展(解耦)
2. 大数据量(1秒 写8万次 读11万次)
3. 数据类型多样(不需要事先设计表)
4. 传统 RDBMS 和 NOSQL
RDBMS
- 结构化组织
- SQL
- 数据和关系都存在单独的表
- 事物的 ACID
NOSQL
- 不仅仅是数据()
- 没有固定查询语言
- 键值对 ,列 ,文档 ,图
- 最终一致性
- CAP定理和 BASE (异地多活)
- 三高(高性能 高可用 高可扩)
分类
KV键值对
Redis
文档型数据库
MongoDB( bson格式 和 json格式一样)
1. 基于分布式文件存储数据库,用来处理大量文档
2. 介于关系型与菲关系型数据库的中间产品
列存储
HBase
分布式文件系统
图关系数据库(图结构数据)
Neo4j
安装
# 安装 c++
yum install gcc-c++
# 建立目录 并上传安装包 redis-5.0.9.tar.gz
mkdir redis
# 解压文件
tar -zxvf redis-5.0.9.tar.gz
# 进入文件 并编译
cd redis-5.0.9
make
# 拷贝文件
cp redis.conf /root/redis
# 安装 这里的 /root/redis 是自定义的redis安装路径
make PREFIX=/root/redis install
# 配置后端启动 Redis
cd ..
vim redis.conf
设置 daemonize yes
# 启动 Redis
./bin/redis-server ./redis.conf
# 查看端口
ps -ef | grep -i redis
root 8385 1 0 19:48 ? 00:00:00 ./bin/redis-server 127.0.0.1:6379
root 8390 3234 0 19:49 pts/0 00:00:00 grep --color=auto -i redis
其他
# 客户端访问 在 bin 目录下 指定端口 ip号 redis-cli -h ip地址 -p 端口号
./redis-cli
# 测试客户端与Redis的连接是否正常
127.0.0.1:6379> ping
PONG
# 退出客户端
127.0.0.1:6379> quit
# 结束 Redis 关闭默认的端口 在 Redis 安装目录下
./bin/redis-cli
shutdown
# 利用第三方软件访问
vim redis.conf
设置 bind + 虚拟机 ip 地址
# 此时如果通过redis客户端访问
./redis-cli -h 192.168.182.132 -p 6379
基础知识
默认有 16 个数据库 默认是第 0 个
Redis 单线程
Redis 基于内存操作, Redis 的瓶颈是根据机器的内存和网络带宽
为什么 Redis 单线程还这么快
Redis 将所有数据放在内存中,所以使用单线程去操作效率高,多线程( CPU 上下文会切换 : 耗时),对于内存系统来说,没有上下文切换的效率就是最高! 多次读写都在一个 CPU 上进行,在内存情况下,最佳方案!
# 切换数据库
select # + index(数据库下标)
# 查看数据库大小
DBSIZE
# 查看所有的 key
keys *
# 清空
flushall # 清空所有数据
flushdb # 清空当前数据
数据类型
命令 : http://www.redis.cn/commands.html
# key-->键 value-->值 time-->时间
# 查看数据类型
type key
# 设置键值对 存在时会更新
set key vlaue
# 查看所有 key
keys *
# 获取 value
get key
# 检查 key 是否存在
exists key
# 移动 key
move key toDB
# toDB 代表移动到哪个数据库
# 设置过期时间
expire key time
# 查看过期时间 time to lose
ttl key
基础数据类型
String
# append 追加字符串 如果 key 不存在,则视为 set
append key appendString
# 查看键对应值(String类型)字符串长度
strlen key
# 自增 自减
incr key # 自增
decr key # 自减
incrby key number # 自增步长
decrby key number # 自减步长
# 获取范围字符串 [start , end]
getrange key start end
# 替换范围字符串 从 start(包括) 开始用 str 替换 不改变后面部分
setrange key start str # hello fangsonghe --> setrange name 2 hell --> "hehellfangsonghe"
# 设置过期时间
setex key time value # set expire
# 当不存在时设置
setnx key value # set if not exist
# 设置多个值
mset k1 v1 k2 v2 ....
# 获取多个值
mget k1 k2 ....
# 设置对象
set key {p1:value,p2:value......} # get user "{name:fang,age:18}"
# 设置多个对象
mset key:{id}:{p1 value} key:{id}:{p1 value} # mset user:1:name fang user:2:age 22
# 获取多个值
mget key:{id}:{p1} # mget user:1 user:2:age 1) (nil) 2) "22"
# 先 get 然后 set 返回原值
getset key value
List
# 可视作双向队列 Left 0 1 2 .. Right
# 在左边添加元素
Lpush key v1 v2 ... # 多个元素会一个个添加 v(n) v(n-1) ... v1
# 在右边添加元素
Rpush key before|after pivot(目标) value
# 获取元素 [start end]
Lrange key start end
# 下标获取元素
Lindex key index
# 插入元素
linsert key index value
# 移除 左边第一个数据
Lpop key
# 移除 右边第一个数据
Rpop key
# 长度
Llen key
# 移除值 count代表移除多少个
Lrem key count value
# 截断 只保留[start end]元素
trim key start end
# 移除列表最后一个元素,并移动到新的 list
rpoplpush fromkey toKey
# 更新元素
lset key index value
set
# 添加元素
sadd key value
# 查看所有元素
sMemebers key
# 检查是否存在 1-->存在 0-->不存在
sIsMember key value
# 元素个数
sCard key
# 删除
srem key v1 v2 ...
# 随机移除一个元素
spop key
# 随机挑选成员
sRandomMember key count(数量)
# 移动成员
smove fromSet toSet value
# 差集
sDiff set1 set2 ...
# 交集
sInter set1 set2 ...
# 并集
sUnion set1 set2 ...
Hash(key-map)
# 添加 map-key 存在时 重写
hset key map-key value
# 添加多个
hmset key k1 v1 k2 v3 ...
# 获取
hget key key
# 获取多个
hmget key k1 k2 ...
# 获取所有 以键值对写出
hgetall key
# 获取所有的 key
hKeys key
# 删除
hdel key map-key
# 元素个数
hlen key
# 检查元素
hExists key map-key
# 自增 自减
incr key map-key # 自增
decr key map-key # 自减
incrby key map-key number # 自增步长
decrby key map-key number # 自减步长
# 当不存在时设置
setnx key map-key value # set if not exist
# 多用于对象的存储
Zset(有序集合)
# 添加
zadd key c1 v1 c2 v2 ...
# inf-->极限
# 排序 升序 在 [min max] 之间
zRangeByScors key min max
# 排序 降序 在 [min max] 之间
zRevRangeByScors key max min
# 查看元素
zRange key min max
# 移除元素
zRem key value
# 查看元素个数
zCard key
# 查看给定区间元素个数
zCount key min max
特殊数据类型
geospatial(地理位置)
# 添加 两级无法直接添加
# 经度 -180 ~ +180
# 维度 -85.05 ~ +85.05
geoAdd key 经度 维度 name
# 获取地理位置
geoPos key name
# 获取两人距离 其中一个不存在 返回空
# km --> 千米 m --> 米 mi --> 英里 ft --> 英尺
geoDist key name1 name2 km
# 以某一点为中心 找某一半径内元素
geoRadius key 经度 维度 半径 km/m/mi/ft
[withdist(显示到中心的距离)] [withcoord(显示经纬度)] [count(查找数量)]
# 以元素为中心
geoRadiusByMember key name 半径 km/m/mi/ft
[withdist(显示到中心的距离)] [withcoord(显示经纬度)] [count(查找数量)]
# 查看
zRange key start stop
# 移除
zRem key name
Hyperloglog(基数)
# 一个集合中不重复元素的个数 {1,2,3,4,5,5} --> 5
# 添加
PFadd key v1 v2 ...
# 统计基数
PFcount key
# 合并
PFmerge key(目标) key1 key2 ...
BitMaps
# 按位存储 0 1
setbit key index 0/1
# 查询
getbit key index
# 统计 默认找 1 的
bitCount key [start end]
ithcoord(显示经纬度)] [count(查找数量)]
查看
zRange key start stop
移除
zRem key name
### Hyperloglog(基数)
```shell
# 一个集合中不重复元素的个数 {1,2,3,4,5,5} --> 5
# 添加
PFadd key v1 v2 ...
# 统计基数
PFcount key
# 合并
PFmerge key(目标) key1 key2 ...
BitMaps
# 按位存储 0 1
setbit key index 0/1
# 查询
getbit key index
# 统计 默认找 1 的
bitCount key [start end]