NoSQL介绍及MongoDB的安装及使用

前言

本篇文章会介绍Nosql和关系型数据库之间的区别,了解NoSQL NoSQL数据库与关系型数 据库有什么不一样。对比关系型数据库理解 MongoDB,MongoDB安装及JAVA客户端使用 ,以及spring对Mongodb的支持。

NoSQL

SQL ,结构化查询语言,这里泛指关系型数据库  。
NoSQL (NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指不提供SQL功能的非关系型数据库。 不遵循,SQL标准、ACID特性、表结构。这个概念很早就有人提出,当时做Not SQL解释,逐渐发展到今天的Not Only SQL。
随着互联网 web2.0网站的兴起,传统的关系数据库在处理web2.0网站,特别是超大规模和高并发的 SNS类型的web2.0纯 动态网站已经显得力不从心,出现了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,特别是大数据应用难题。
这也是现在nosql兴起的原因。
这个也是对比现在流行的关系型数据库上自己的特性。
传统型数据库的特点,结构化  二维表  E-R关系 sql标准化  支持锁  事务 ACID 索引  为了保证数据的安全 ,做了大量的处理。
对比出 Nosql数据库  为了高并发等  特性,因此不会遵从 传统型数据库的特点。
存储方式 采用k-v的方式

最开始因为简单  快速  使用nosql,到现在的sql,不断的进化, 然后发觉sql并不能满足时,有兴起了nosql数据库

为什么需要NoSQL

  • 现代网站服务,是超大规模和高并发的SNS类型的web2.0纯动态网站
  • 传统关系型数据库遇到了性能、扩展瓶颈
  • NoSQL数据库为了解决大规模数据集合、多重数据种类带来的挑战而产生
  • 应用在大数据应用难题,包括超大规模数据的存储

为了性能 一直在努力,一直在寻找着解决方案。

四大类NoSQL数据库

对于不同的场景进行选择不同nosql数据库,包括我在项目中 进行大数据量数据分析,采用hbase是非常使用的,当然还有现在比较流行的clickhouse等。

如果 数据库表中 有大量的null值,在关系型数据库中非常占资源的,而如果采用列式存储方式换一个角度 ,没有就不存,对于结构要求不是很严格 采用列式存储是非常有效的。功能是有限的,例如id去查不方便去查。

 

功能不能像传统型数据库一样做到sql支持完整。

对于文档存储方式,数据结构要求不严,表的结构可以变化,查询性能要求不高。实现的方式 大部分存储方式是json格式,包括es 和 mongodb都是的,  都是自定义的一套操作语法。

mapreduce、全文检索实现方式不一样的,这都是es和mongdb不同的地方。

包括上面的 利用图结构相关算法的数据库 这个一般很少使用的数据库。在地图这些应该用到很多。

针对这些的排名情况。

DB-Engines Ranking - popularity ranking of database management systems

 最高的还是oracle  我觉得得益于政府  大企业的使用,  其实 SQlite数据库来说,我觉得还是得益于android手机 确实还是比较火的。

包括其他的一些排行榜数据库

NoSQL与传统数据库对比

这在对比起来,因为方向不一样,所以 各自的特点不一样,包括 强一致性 和弱一致性,都是 为了提高某一部分的能力提高,因此才用的结构。 一级  二维和多维表   json格式等。提高存储,以及大数据量的问题,并且对于事务这些问题,因此都会分开 nosql  关系型数据库的概念。

这些一般关系型数据库的优点 其实就是nosql数据库的缺点,反之, 也是得益于存储结构导致的。

Mongo核心概念

MongoDB是一个基于C++开发的NoSQL开源文档数据库,具有所需的可伸缩性和灵 活性,可用于所需的查询和索引编制。最像关系数据库,功能最丰富的NoSQL数据库。

特性
  • 面向集合文档的存储:适合存储Bson(json的扩展)形式的数据;
  • 格式自由,数据格式不固定,生产环境下修改结构都可以不影响程序运行;
  • 强大的查询语句,面向对象的查询语言,基本覆盖sql语言所有能力;
  • 完整的索引支持,支持查询计划;
  • 支持复制和自动故障转移;
  • 支持二进制数据及大型对象(文件)的高效存储;
  • 使用分片集群提升系统扩展性;
  • 使用内存映射存储引擎,把磁盘的IO操作转换成为内存的操作;

主要和js语言很像,所以书写时也比较简单了。而且在互联网公司中应用是非常广泛的。

应用需求和特点
  • 不需要事务及复杂join支持
  • 新应用,需求会变,数据模型不确定,想快速迭代开发
  • 要应对2000-3000以上的读写QPS(或更高)
  • 要存储TB甚至PB级别数据
  • 只要有一项需求满足就可以考虑
  • 应用发展迅速,能快速水平扩展
  • 匹配越多,选择MongoDB越合适
  • 要求存储的数据不丢失
  • 要求99.999%高可用
  • 有大量的地理位置查询、文本查询

这都是为什么要使用mongdb 情况。

使用场景

MongoDB 的应用已经渗透到各个领域,比如游戏、物流、电商、内容管理、社交、物联网、视频直播等,以下是几个实际的应用案例:
  • 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储, 方便查询、更新
  • 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以MongoDB嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
  • 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引 实现附近的人、地点等功能
  • 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这 些信息进行多维度的分析
  • 视频直播,使用 MongoDB 存储用户信息、礼物信息等

都是得益于mongodb的自带的优缺点导致的。

不适合使用MongoDB

1. 高度事务性系统:例如银行、财务等系统。MongoDB对事物的支持较弱;
2. 传统的商业智能应用:特定问题的数据分析,多数据实体关联,涉及到复杂的、高度优化的查询方式;
3. 使用sql方便的时候;数据结构相对固定,使用sql进行查询统计更加便利的时候;

基本概念

  • 实例:系统上运行库的进程及节点集,一个实例可以有多个库
  • 库:多个集合组成数据库,每个数据库都是完全独立的,有自己的用户、权限信息,独立的存储文件集
  • 集合:即一组文档的集合,文档是存放的数据。集合内的文档结构可以不同
  • 文档:MongoDB数据库的最小数据集单位,其基本概念为:多个键值对有序组合在一起的数据单元

很多文档进行逻辑分组。

与关系型数据库对比

MongoDB文档类似于JSON对象,称为BSON。字段的值可以包括其他文档,数组和文档数组。

在bson里面有内嵌文档 可以相当于类似面向对象类型。

使用文档存储的优点:
  • 文档(即对象)对应于许多编程语言中的本机数据类型
  • 嵌入式文档和数组减少了对连接的需求
  • 动态模式支持流畅的多态性

 数据类型

Bson是JSON文档的二进制表示形式,它包含比JSON更多的数据类型。

MongoDB中,一个BSON文档最大大小为16M,文档嵌套的级别不超过100

 在mongodb中可以使用其他类型来存大对象 gridFS用来解除大块文件限制的问题

 MongoDB安装

tgz方式安装

下载解压
tgz 是一个免安装包的方式,需要手工配置 MongoDB 启动需要的对应文件。
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.1.tgz
tar -vzxf mongodb-linux-x86_64-rhel70-4.2.1.tgz 
mv mongodb-linux-x86_64-rhel70-4.2.1 /usr/local/mongodb
cd /usr/local/mongodb
配置
免安装包没有创建日志、数据的默认目录及文件。这里不使用默认的目录文件,自己定义数据目录和日志文件。
mkdir -p /usr/local/mongodb/logs /usr/local/mongodb/data # 创建目录备用 
vim /usr/local/mongodb/logs/mongodb.log # 创建一个空日志文件即可 
vim /usr/local/mongodb/bin/mongodb.conf # 创建MongoDB的配置文件
mongodb.conf 文件内容如下
# MongoDB的配置文件,mongod.conf 
# 配置文件全部配置参考下面网址: 
# http://docs.mongodb.org/manual/reference/configuration-options/ 
# 写入日志数据的位置 
systemLog: 
    destination: file 
    logAppend: true 
    path: /usr/local/mongodb/logs/mongodb.log 
# 存储数据的地点和方法 
storage: 
    dbPath: /usr/local/mongodb/data 
    journal: enabled: true 
# engine: 
# wiredTiger: 
# 进程如何运行 
processManagement:
    fork: true # 是否启用子进程在后台运行 
    pidFilePath: /usr/local/mongodb/mongod.pid # pidfile的位置 
    timeZoneInfo: /usr/share/zoneinfo 
# 网络配置 
net:
    port: 27017 # 默认端口号 
    #bindIp: 127.0.0.1 # 设定ip地址白名单,此处我们注释掉为了方便学习 
# 方便学习改为true,生产环境则使用白名单 
    bindIpAll: true # 是否允许所有的ip地址访问,默认是false
操作
cd /usr/local/mongodb 
sudo bin/mongod -f bin/mongodb.conf 
# 通过制定配置文件来启动 
# 通过kill命令关闭进程来关闭mongodb
操作 MongoDB
MongoDB 启停重启操作如下
sudo service mongod start # 启动 
sudo service mongod stop # 停止 
sudo service mongod restart # 重启
通过查看日志,看启动过程
sudo tail -f /var/log/mongodb/mongod.log
使用 MongoDB
通过 mongo 命令,作为客户端来直接访问启动的本地服务

进程介绍
mongod mongod MongoDB 系统的主要守护进程。它处理数据请求,管理数据访问并执行后台管理操作。
mongod 进程,支持通用配置、存储引擎、集群、监控、安全协议等配置。
sudo /usr/bin/mongod --help
mongo , 是 MongoDB 的交互式 JavaScript Shell 界面。提供了强大的界面,并为开发人员提供了一种直接通过数据库测试查询和操作的方式。 mongo 还提供了用于 MongoDB 的功能齐全的 JavaScript 环境。
# 连接本地默认端口 
sudo /usr/bin/mongo 
# 连接远程 
sudo /usr/bin/mongo -u <user> -p --host <host> --port 28015
mongos , 提供客户端应用程序和分片群集之间的接口。该 mongos 实例路线查询和写入操作碎片。从应用程序的角度来看,一个mongos 实例的行为与任何其他 MongoDB 实例相同。
sudo /usr/bin/mongods --help
mongostat ,提供了当前正在运行 mongod mongos 实例的状态的快速概述。功能上类似于 UNIX /
Linux 文件系统实用程序 vmstat ,还提供有关 mongod mongos 实例的数据 。
mongotop ,跟踪 MongoDB 实例 mongod 花费在读写数据上的时间的方法。
mongoreplay ,是 MongoDB 的流量捕获和重播工具,可用于检查和记录发送到 MongoDB 实例的命
令,然后在以后将这些命令重播到另一台主机上。
mongofifiles ,实用程序使您可以从命令行操作 GridFS 对象中存储在 MongoDB 实例中的文件。它提供了
存储在文件系统中的对象与 GridFS 之间的接口,因此它特别有用。

安装图形界面compass

MongoDB Compass MongoDB 的图形界面。不需要正式了解 MongoDB 查询语法,就可以通过
Compass 分析和理解数据的内容 。除了在可视化的环境中浏览数据外,还可以使用 Compass 来优化查询性能, 管理索引和实施 文档验证。类似于Oracle PLSQL MySQL SQLyog 图形化操作界面。
安装 compass
compass 支持 windows linux macos 三个类型的操作系统安装,如果你还想安装其他系统的版本,操作请参考 官网安装文档
安装依赖:
  • 64Windows7以上的操作系统
  • MongoDB3.6 以上
  • Microsoft .NET Framework version 4.5以上
安装
  • 1. 到官网下载windows版本zip格式的安装包
  • 2. zip文件移动到你想要放置的目录,解压zip文件到mongodb-compass目录
  • 3. 进入mongodb-compass目录,双击MongoDBCompass.exe运行文件
连接 MongoDB
跳过欢迎界面,来到连接 MongoDB 的界面,填写连接信息点击连接,即可连接 MongoDB

 使用MongoDB

通过Mongo shell操作学习如何使用MongoDB相关内容
./mongo
操作数据库、集合
db # 显示当前数据库
use dataBaseName # 如果dataBaseName不存在,在插入数据时将会创建数据库
show dbs # 显示当前实例中的数据库
db.dropDatabase() # 删除当前选择的库
db.createCollection("runoob") # 显式的创建runoob集合
show tables # 显示当前数据库中的集合信息
show collections
db.runoob.drop() # 删除runoob集合

新建操作语法

新建文档
新文档添加到集合中。如果该集合当前不存在,则插入操作将创建该集合。
db.collection.insertOne()
#插入单个文档
db.collection.insertMany() #插入多个文档
db.collection.insert()
#插入单条或多个文档
插入操作行为影响:
  • 自动创建不存在的集合、数据库,例如这里的inventory集合
  • 如果不指定,自动生成主键_id及其值
  • 写操作都是基于单个文档级别的原子操作
  • 确认写操作级别,在分片集群中我们需要关注,目前忽略
MongoDB下新建文档的语法如下:
db.collection.insert(
<document or array of documents>,
{
writeConcern: <document>,
ordered: <boolean>
} )
documents:必填,表示需要插入的文档,可以是多个文档
writeConcern:可选项,写策略,后面学习集群时我们再关注
ordered:可选,表示多个文档是否按照文档顺序插入

查询操作

查询文档
在inventory集合中,查询我们插入的记录
# SELECT * FROM inventory WHERE item = "canvas"
db.inventory.find( { item: "canvas" } ).pretty()



# SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")
db.inventory.find( {
    status: "A",
    $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )

这就是查询的语法。

在加上本身的内嵌文档中数据查询   in all   满足一个就行,全部满足

 

查询摘要

MongoDB 查询数据的语法格式如下:
db.collection.find(query, projection)
  • query :可选,使用查询操作符指定查询条件
  •  projection :可选,使用投影操作符指定返回的键。查询时返回 文档中所有键值, 只需省略该参数即可(默认省略)。
  •  需要以易读的方式来读取数据,可以使用 pretty() 方法;
操作符

 这都是逻辑符,这个是通用的。

查询其他操作

映射
  •  字段选择:db.inventory.find({},{'item':1})
  •  字段排除: db.inventory.find({},{'item':0})
  •  数组子元素选择:db.inventory.find({},{'tags':{'$slice':[1,2]},'tags':1}) $slice可以取两个元素数组,分别表示跳过和限制的条数;

排序
sort():db.orders.find().sort( {'orderTime':1,'price':1} ) 1:升序 2:降序
跳过和限制
  skip(n):跳过n条数据
limit(n):限制n条数据  e.g:db.orders.find().sort({'orderTime':-1}). limit(5).skip(5)
查询唯一值
distinct():查询指定字段的唯一值   e.g:db.users.distinct("age")
在插入时就把数据间的关系放进去,查询时就非常快的。
这都是类似于标准sql而开发的。

 

slice限制数组返回的内容  从1开始。
内嵌文档, 进行查询  这个类似于page 分页的概念。
包括  下面的  匹配null  不存在的字段数据信息。

这在使用中可以用得到。

// 分页查询,并排序
// offset limit
db.inventory.find().skip(2).limit(2).sort({qty:1});
db.inventory.find().sort({qty:1});

聚合函数

// 单用途聚合操作
db.inventory.distinct("status");
// 要避免不通过查询器,直接使用count方法,会导致近似计数。
db.inventory.find({ status: "A" }).count();  // 4.0弃用
// 基于count方法而来,估算集合中的文档数
db.inventory.estimatedDocumentCount({});
// 通过对数据进行统计的,返回准确的计数,通过聚合计算而来
db.inventory.countDocuments({ status: "A" })

包括 去重统计这些操作。统计集合中状态为A的文档数
// 统计集合中状态为A的文档数
db.inventory.aggregate([
   { $match: { status: "A" } },
   { $group: { _id: null, totalStatusADoc: { $sum: 1 } } }
])

计算  和估算操作,map-reduce.进行聚合查询。

统计可用物品这些。

更新操作语法

更新文档的几种方式
db.collection.updateOne()
db.collection.updateMany()
db.collection.replaceOne()
更新操作行为:
  • 所有写操作都是单个文档级别的原子操作
  • _id无法被修改
  • 更新操作对字段顺序的影响,一般都保留文档字段的原始顺序
_id字段始终是文档中的第一个字段
更改字段名,可能导致字段顺序发生变化
更新摘要
  • query,查询条件,类似sql update查询的where
  • update,update的对象和一些更新的操作符(如 $,$inc...)等,类似sql update查询的set
  • upsert,可选,表示如果记录不存在,是否插新文档,true为插入,默认false,不插入
  • multi,可选,默认false,只更新找到的第一条记录。true,匹配的多条记录全部更新
  • writeConcern,可选,写策略
  • collation,可选,索引语言规则
  • arrayFilters,可选,过滤文档数组,用于确定更新操作要修改数组中的具体元素
  • hint,可选的,指定查询希望使用的索引字段,如 果没有这个索引就会报错

这都是更新操作。

更新操作符

 

 更新单个文档,会更新第一个匹配到的文档

// UPDATE inventory SET size.uom='cm', status='P', lastModified=now() WHERE item = "paper" 
db.inventory.updateOne(
   { item: "paper" },
   {
     $set: { "size.uom": "cm", status: "P" },
     $currentDate: { lastModified: true }
   }
)

 批量更新

// UPDATE inventory SET size.uom='in', status='P', lastModified=now() WHERE qty < 50
db.inventory.updateMany(
   { "qty": { $lt: 50 } },
   {
     $set: { "size.uom": "in", status: "P" },
     $currentDate: { lastModified: true }
   }
)
db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)

把文档做掉进行更新。

直接隐式转换,

可以支持任意修改已存在字段的数据类型,直接转换数字

通过面向文档,可以 进行修改。更新字段名称等。

 

 往tags数组中增加元素,如果tags字段不存在则会新增该字段,如果值有重复就不处理

数组中添加数组元素,并不是添加多个值

通过$each,往数组中添加多个值

更新所有记录,删除tags数组的red、big元素

db.inventory.find({ tags: { $in: ["red", "big"] } })
db.inventory.update(
    { },
    { $pull: { tags: { $in: [ "red", "big" ] }} },
    { multi: true }
)

删除length数组中包含50/90的元素

// 删除length数组中包含50/90的元素
db.inventory.update( { item: "apple" }, { $pullAll: { length: [ 150, 390 ] } } )

// 从前弹出一个元素,类似队列的pop api
db.inventory.update( { item:"mobile"}, { $pop: { scores: -1 } } )
// 从后弹出两个元素
db.inventory.update( { item:"mobile"}, { $pop: { scores: 2 } } )

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踩踩踩从踩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值