黑马程序员技术交流社区

标题: 【西安校区】Mongodb入门 [打印本页]

作者: 西安Java组    时间: 2018-4-18 15:17
标题: 【西安校区】Mongodb入门
Mongodb是目前最流行的基于文档类型的开源NoSQL数据库,NoSQL意味着Not Only SQL,它和传统的关系型数据库不一样,它是通过BSON的格式来存储,BSON其实就相当于JSON,它在JSON的基础上进行了一些类型扩展,
就是一个基于JSON的二进制存储格式。
* Mongodb和传统的关系型数据库有很多区别,当然Mongodb的出现并不是用来替代关系型数据库中,它有自己的适用领域,在如今的大数据时代中,数据库的分布式需求已经变成的常规系统,伯克利分校的教授Brewer提出了一套CAP理论,该套理论也就是如今的NoSQL的理论模型。

该套理论提出对于分布式的数据库设计而言,至少要满足CAP中的三种中的两种,C(Consistency)表示一致性,说明分布式的数据库系统中每个接点数据都是一致的;A(availability)表示可用性,数据库系统读写的值是最新的,P(Partition tolerance)表示分区容错机制,就是任何分离的接点都能独立完成任务。这三者不可兼得,所以任何的数据库模型都只能满足其中的两种,而基于Document的Mongodb主要是基于CP来进行设计的,目的是为了快速的读取分布式的数据,所以它在可用性:如果事务处理等方面就稍微差一些。而MySQL等的关系型数据主要兼容了CA,它的分布式的容错就差一些。而且对于海量数据而言,关系型数据库的join操作效率也不是很理想。
###Mongodb的安装###
* 首先通过Mongodb的官方网站下载Mongodb,[官方网站](https://www.mongodb.com),点击download进入下载页面


之后选择Community Server,这里的Download所下载的版本是安装版,个人更喜欢使用绿色版,所以需要点击All Version,下载绿色版,如下图所示:


* 下载完成之后,解压文件到相应的文件夹中,我是保存在d:/mongodb文件夹中,接着需要配置bin路径到环境变量的path中,之后以管理的身份打开命令提示符,如果是win10的系统,可以通过win+x选择管理员命令提示符。
* 首先要创建一个文件夹来存储Mongodb的数据库,个人习惯在Mongodb的目录中创建这个文件夹。
  PS D:\> cd mongodb
  PS D:\mongodb> mkdir data
* 然后通过mongod命令启动Mongodb,第一次会完成安装操作,然后启动Mongodb。
  PS D:\mongodb> mongod --dbpath d:/mongodb/data
![alt text](images/2018-04-01_192612.png)
* 启动之后默认的端口是27017,但是处于一种阻塞的状态,此时需要开启另外一个命令提示符可以进入Mongodb。打开新的命令提示符(不用管理员身份)之后,直接输入mongo即可打开Mongodb
  

* 已上操作是一种常规的安装方法,这种方法最大的问题就是不小心把阻塞的窗口关了,也就无法访问Mongodb了,所以建议以后台的方式来启动,但是windows没有linux中的-fork命令,所以需要将其添加到服务管理中。
###Mongodb安装到服务管理中###
* 安装的第一步是创建一个配置文件,通过该文件设置Mongodb的基本配置信息,在Mongodb的目录中创建一个mongodb.cfg的配置文件,在文件中加入日志,等配置信息.

  systemLog:
     destination: file
     path: d:/mongodb/log/mongo.log
     logAppend: true
  storage:
     dbPath: d:/mongodb/data
  net:
    bindIp: 127.0.0.1
    port: 27017

* 以管理员身份进入命令提示符,输入命令:
  PS D:\mongodb> mongod --config "d:/mongodb/mongodb.cfg" --install
* 这样就完成了安装,通过服务管理器,可以查询windows的系统服务,就可以找到MongoDB的一个服务,通过
  net start MongoDB
* 启动Mongodb的服务,也可以在服务管理器中设置为自动启动。通过命令
  net stop MongoDB
* 可以停止服务。默认的端口是27017。通过以上步骤即可完成Mongodb的安装操作。
###Mongodb的删除###
* 这里主要讲解安装在服务管理器中的Mongodb的卸载,如果不是服务管理器中的,直接删除目录即可,此时只要不删除data文件夹,数据库信息也不会丢失(所以在生产环境中,data的目录应该不要放在Mongodb文件夹中)。通过几个简单的命令即可完成Mongodb的删除。
* 首先停止服务
  net stop MongoDB
* 删除服务管理器中的mongodb
  mongod --remove
* 此时会得到如下提示:
  PS D:\mongodb> mongod --remove

  2018-04-01T04:00:42.283-0700 I CONTROL  [main] Trying to remove Windows service 'MongoDB'

  2018-04-01T04:00:42.284-0700 I CONTROL  [main] Service 'MongoDB' removed
* 检查一下服务管理器,发现MongoDB服务已经被删除了,最后只要删除Mongodb目录即可。
###小结###
* 这一部分内容简单介绍了Mongodb的安装和删除,操作非常的简单,但在实际的生产环境中,还是建议在Linux下面进行操作,下一部分将主要介绍Mongodb的基本使用。

##MongoDB的基本操作##
* 对MongoDB的操作可以通过MongoDB shell进行操作,只要在命令提示符中输入mongo即可开启MongoDB的shell脚本,在shell可以完成对MongoDB数据库的所有操作。
  > db

  test
* 使用db命令可以查询当前所使用的库,通过use命令可以打开一个新的数据库,如果数据库存在,会打开,如果数据库不存在会创建数据库。

  > use demo

  switched to db demo
  
  > db
  
  demo
* 对于MongoDB而言,它虽然和关系数据库的存储结构不一样,但有些思路是可以相通,在关系数据库中,使用表来存储实体信息,而MongoDB使用Collection来存储,collection就相当于关系数据库中的表。MongoDB中使用Document来表示关系数据库中的row(每一行记录),但MongoDB中的Document是基于JSON的方式来编写的,每个document都是通过key和value来存储字段,这就相当于关系数据库中的Column。通过db.collection.insertOne可以插入一条数据。
  > db.user.insertOne({username:"zs",nickname:"zhangsan",password:"123"});

  {
          "acknowledged" : true,

          "insertedId" : ObjectId("5a0ed29a0149542ec19d4dd8")
  }
* 已上命令完成了数据库插入操作,db.user等于创建了一张user的表,insertOne后的内容就等于插入了一条数据,这个格式和json的格式一模一样,添加完成之后,会自动生成一个id。只要数据库中有数据之后就会自动存储到硬盘上,此时使用show dbs即可查询系统中的数据库

  > show dbs

  admin  0.000GB
  
  demo   0.000GB
  
  local  0.000GB
* 我们发现此时已经有三个数据库,admin和local是系统默认的,demo是刚刚创建的。继续再插入一条数据
  db.user.insertOne({username:"foo",age:22,nickname:"foobar",password:"111"});
  {
          "acknowledged" : true,
          "insertedId" : ObjectId("5a0ed40b0149542ec19d4dd9")
  }
* 注意在这条数据中多添加了一个名为age的key,这就是MongoDB和关系数据库最大的区别,关系数据库中需要先设计相应的schema,而MongoDB不用进行设计,可以灵活的处理各种情况。使用find命令可以查询collection中的所有记录。
  > db.user.find().pretty() ##查询user这个collection中的所有数据(document)
  {
          "_id" : ObjectId("5a0ed29a0149542ec19d4dd8"),
          "username" : "zs",
          "nickname" : "zhangsan",
          "password" : "123"
  }
  {
          "_id" : ObjectId("5a0ed40b0149542ec19d4dd9"),
          "username" : "foo",
          "age" : 22,
          "nickname" : "foobar",
          "password" : "111"
  }
* 通过exit命令可以退出MongoDB

  > exit
  bye
###安装可视化管理工具###
* 使用MongoDB的shell可以直接操作数据库,也有现成的一些数据库管理工具帮助我们操作MongoDB,MongoDB官方网站的MongoDB Compass也是比较好用的可视化工具,它是免费的,另外Robo 3T也推荐使用,它是原来的Robomongo 的最新版本,同样是免费的。
* 我比较常用的工具是Robo 3T,之所以推荐使用Robo 3T,是因为其实可视化的功能效率并没有直接操作shell高,但使用Robo 3T实际的操作还是以shell的脚本为主,使用Robo 3T比较简单,只要创建一个本地连接即可,前提是MongoDB已经正常启动。第一次进入首先要创建一个新连接
![alt text](images/3735524-7df831a6e9133f42.png)
* Robo 3T创建新连接
之后选择Direct Connection(直接连接),确定地址(127.0.0.1)和端口(27017)


Robo3T 建立连接
连接成功之后会显示下图,我们可以看到我们的数据库demo。

* 右键点击该数据库,选择open shell打开MongoDB的shell脚本,可以通过shell进行数据库的操作。
![alt text](images/3735524-28dd55085708911b.png)
* Robo3T 打开shell脚本
至此,MongodDB工具已经安装完成,接下来就可以进行数据库的基本操作了。
###数据库和数据集合的基本操作###
####数据库的基本操作####
* 数据库的操作比较简单,通过use可以创建和打开数据库,通过dropDatabase可以删除数据库,通过db可以查询当前的数据库,通过show dbs可以查询数据库。
  > use testDb ##创建并且选择数据库
  >
  switched to db testDb

  > db ##查询当前数据库
  
  testDb

  > show dbs ##显示所有数据库
  
  admin  0.000GB

  demo   0.000GB

  local  0.000GB
* 此处并没有显示新创建的数据库testDb,因为该数据库没有任何的数据,所以只会存储在内存中,如果此时退出shell,该数据库并不会存储,只要插入一条数据之后就会完成存储
  > db.testCollection.insertOne({name:"test"}); ##插入一条数据
  {
          "acknowledged" : true,
          "insertedId" : ObjectId("5a0ef48d82b7673e378848b8")
  }
  > show dbs ##显示所有的数据库,此时有数据了,所以数据库完成存储
  admin   0.000GB
  demo    0.000GB
  local   0.000GB
  testDb  0.000GB
* 通过db.dropDatabase()即可删除数据库,此时删除的是当前库
  db.dropDatabase() ##删除数据库
  { "dropped" : "testDb", "ok" : 1 }
  > show dbs
  admin  0.000GB
  demo   0.000GB
  local  0.000GB
* MongoDB的Collection的基本操作
* MongoDB中的Collection就相当于关系数据库中表,对表也有基本的操作,通过createCollection可以创建一个Collection。也可以通过文档操作来创建Collection(db.tt.insertOne(),此时如果没有tt这个Collection会自动创建)。通过show collections可以查询所有的collection,通过drop()可以删除一个Collection,具体命令如下
  > use testDb  ##创建数据库
  switched to db testDb
  > db.createCollection("t1") ##创建一个collection为t1
  { "ok" : 1 }
  > db.t2.insertOne({foo:"bar"}) ##通过Document的操作也可以创建Collection
  {
          "acknowledged" : true,
          "insertedId" : ObjectId("5a0ef79f82b7673e378848b9")
  }
  > show collections ##查询所有的Collection,有t1和t2两个
  t1
  t2
  > db.t1.drop() ##删除t1这个collection
  true
  > show collections ##查询所有的Collection
  t2
###Document的基本操作###
* MongoDB中的文档(Document)就是具体数据,也是MongoDB的核心,下面将简单的演示基于Document的几种操作,有个直观的感受之后,来详细介绍Document中的各类常用操作。
####Document的插入####
* 可以通过db.collection.insertOne()插入一条数据,可以通过db.collection.insertMany()批量插入,(由于MongoDB的更新比较大,这些命令都是在3.2版本之后才有,个人使用的是3.4这个最新版。)
  > db.t2.insertOne({name:"foo",age:22}) ##插入一条数据
  {
          "acknowledged" : true,
          "insertedId" : ObjectId("5a0efa2082b7673e378848ba")
  }
  > db.t2.insertMany([
  ... {name:"t1",age:33},
  ... {name:"t2",age:44}
  ... ]) ##插入多条数据
  {
          "acknowledged" : true,
          "insertedIds" : [
                  ObjectId("5a0efa5b82b7673e378848bb"),
                  ObjectId("5a0efa5b82b7673e378848bc")
          ]##提示插入了两条数据
  }
####Document的查询#####
* 查询是数据库中最为重要的操作,这里先简单演示几种查询操作,之后会详细的介绍一些非常流行的查询方式,通过db.collection.find()可以查询数据,同样可以基于json的格式来添加查询的条件
  
  > db.t2.find() ##查询所有信息
  { "_id" : ObjectId("5a0ef79f82b7673e378848b9"), "foo" : "bar" }
  { "_id" : ObjectId("5a0efa2082b7673e378848ba"), "name" : "foo", "age" : 22 }
  { "_id" : ObjectId("5a0efa5b82b7673e378848bb"), "name" : "t1", "age" : 33 }
  { "_id" : ObjectId("5a0efa5b82b7673e378848bc"), "name" : "t2", "age" : 44 }
  > db.t2.find({name:"t2"})##查询名称为t2的信息
  { "_id" : ObjectId("5a0efa5b82b7673e378848bc"), "name" : "t2", "age" : 44 }
  > db.t2.find({age:{$lt:25}})##查询age小于25的所有信息
  { "_id" : ObjectId("5a0efa2082b7673e378848ba"), "name" : "foo", "age" : 22 }
####Document的更新####
* 更新操作也非常简单,使用db.collection.updateOne()更新一条记录,通过db.collection.updateMany()更新多条记录,使用db.collection.replaceOne()替换信息,此时需要使用$set来进行更新的设定,这几个操作中的第一个参数都是更新条件,第二个参数都是具体的值的设置
   db.t2.updateOne({name:"t1"},{$set:{age:35}}) ##更新一条信息,将name为t1的记录的age设置为35
  { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
   db.t2.find({name:"t1"})##成功完成更新
  { "_id" : ObjectId("5a0efa5b82b7673e378848bb"), "name" : "t1", "age" : 35 }

* 接下来看一下批量更新
* 批量更新,将age大于等于35的的记录增加foo这个信息,由于没有foo,所以会增加这个记录
  > db.t2.updateMany({age:{$gte:35}},{$set:{foo:"bar"}})
  { "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
  > db.t2.find({age:{$gte:35}})##所有的信息增加了这个记录
  { "_id" : ObjectId("5a0efa5b82b7673e378848bb"), "name" : "t1", "age" : 35, "foo" : "bar" }
  { "_id" : ObjectId("5a0efa5b82b7673e378848bc"), "name" : "t2", "age" : 44, "foo" : "bar" }
*通过这个操作,我们发现MongoDB可以不受限制的增加Document中的key和value的对应关系,这和关系型数据库有极大的区别,最后来看一下替换操作
  > db.t2.replaceOne({name:"foo"},{name:"ok",foo:"bar",hello:"world"})##替换name为foo的数据
  { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
  > db.t2.find({name:"foo"})##name已经修改,这个记录查询不到数据
  > db.t2.find({name:"ok"})##完成替换
  { "_id" : ObjectId("5a0efa2082b7673e378848ba"), "name" : "ok", "foo" : "bar", "hello" : "world" }
  >

####Document的删除操作####
* Document的删除操作同样有db.collection.deleteOne()和db.collection.deleteMany()两种,前者是删除一条记录,后者删除多条记录

  > db.t2.deleteOne({name:"ok"})##删除名称为ok的一条记录
  { "acknowledged" : true, "deletedCount" : 1 }
  > db.t2.deleteMany({age:{$lt:40}})##删除age小于40的记录
  { "acknowledged" : true, "deletedCount" : 1 }
  > db.t2.find()##查询结果
  { "_id" : ObjectId("5a0ef79f82b7673e378848b9"), "foo" : "bar" }
  { "_id" : ObjectId("5a0efa5b82b7673e378848bc"), "name" : "t2", "age" : 44, "foo" : "bar" }

###小结###
* 这一部分介绍了MongoDB的基本操作和IDE,并且讲解了数据库和数据集合的基本操作,最后讲解了Document的CRUD操作,通过这些介绍,我们发现由于没有schema的限制,MongoDB非常的灵活,字段的键值对可以随意修改,这在很多场合都会体现出特有的优势,下一部分将讲解MongoDB的开发人员的设计原则。








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2