mongodb必会知识点_mysql

By CaesarChang 张旭           

1 简介: 

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。MongoDB是一个介于关系数据库和非关系数据库之间的产品,


它支持的数据结构非常松散,是类似json的bson,含义为Binary JSON(二进制JSON)


1.2 特点

(1) 面向集合存储,易存储对象类型的数据

(2) 支持动态查询

(3) 支持完全索引,包含内部对象

(4) 支持复制和故障恢复

(5) 支持多种开发语言

(6) 使用高效的二进制数据存储,包括大型对象 ( 如视频等 )


1.3  适用场景


1 )网站实时数据处理。它非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及

高度伸缩性。

2 )缓存。由于性能很高,它适合作为信息基础设施的缓存层。在系统重启之后,由它搭建的持久化缓

存层可以避免下层的数据源过载。

3 )高伸缩性的场景。非常适合由数十或数百台服务器组成的数据库,它的路线图中已经包含对

MapReduce 引擎的内置支持。

 

2.基本操作

mongodb必会知识点_mongodb_02

2.1支持的数据类型:

3.1 null

   null用于表示空值或不存在的字段。示例如下:{"x" : null}

3.2 布尔类型

   布尔型数据有 true 和 false两个值。示例如下:{"x" : true}

3.3 数值类型

   在 Mongo shell 中,默认使用 64 位浮点型数据。因此,会有以下两种数值形式:

{"x" : 2.32}// 或 {"x" : 2}

   对于整数类型,可以使用 NumberInt()( 位有符号整型 ) 或 NumberLong()(8 位有符号整型 ) 方法进行转

换。示例如下:


{"x" : NumberInt(2)}

{"x" : NumberLong(2)}


3.4 字符串

  MongoDB 中字符串类型使用 UTF-8 编码的字符表示。示例如下:

{"x" : "123@qq.com"}

3.5 日期类型

  MongoDB 中日期使用时间戳表示,单位为毫秒,不存储时区。示例如下:

创建日期对象时应该使用 new Date() ,而非构造函数 Date() 。将构造函数作为函数时返回的日期格式

是字符串,而非日期对象(与 JavaScript 工作机制有关)。

{"x" : new Date()}

3.6 正则表达式

  MongoDB 中可使用与 JavaScript 相同的正则表达式进行查询筛选等。示例如下:

{"x" : /www/i}

3.7 数组

  数据集可以用数组格式存储,与 JavaSript 中的数组表示相同。示例如下:

数组中可以包含不同类型的数据元素,包括内嵌文档和数组等。所有 MongoDB 中键 - 值对支持的数据

类型都可以用做数组的值。

{"x" : ["kaikeba", "kaikeba.com"]}

3.8 内嵌文档

  文档中可以嵌套一个子文档。在 MongoDB 文档总大小限制为 16MB ,建议使用子文档的形式组织数

据,子文档查询效率要高于多键查询。示例如下:

文档可以做为键的值,即:内嵌文档。 MongoDB 与关系型数据库相比,最大的优势就是内嵌文档。

与关系型数据库的扁平化数据结构相比,使用内嵌文档可以数据的组织方式更加自然。

{"x" : {"kaikeba" : "kaikeba.com"}}

3.9 _id ObjectId

  MongoDB 中每个文档都有一个 " id" 键, " id" 可以是任何类型,不指 "_id" 时 MongoDB 会生成一个

ObjectId 对象。。示例如下:

ObjectId 是一个 12 字节( 24 个十六进制数字)的存储空间, ObjectId 的 12 字节数据组织方式如下:

对于如下一个 ObjectId ,其各位字符含义为:

{"_id" : ObjectId()}

 

 

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

     时间戳   | 机器码   | PID  |    计数器     {"_id" : ObjectId("5444cce6aef53b0f343e2b9b")}

/* 上面 ObjectId 各位字符含义如下 */

//5444cce6 ,第 0 〜 3 字节(第 1 〜 8 位)为时间戳

//aef53b ,第 4 〜 6 字节(第 9 〜 14 位)为机器码

//0f34 ,第 7 〜 8 字节(第 15 〜 18 位)为进程 ID

//3e2b9b ,第 9 〜 11 字节(第 19 〜 24 位)为自增计数器

3.10 代码

  MongoDB 的文档和代码中可以包括 JavaScript 代码。示例如下:

{"x" : function()  { /* 这里是一段 JavaScript 代码 */} }

3.11 二进制数据

  二进制数据是一个二进制字节的字作串,要保存非 UTF-8 字符到数据库中,只能使用十进制数据

4.0常用操作

查看数据库(数据库中至少有一条数据,此时的数据库才会显示出来)

  >show dbs

切换数据库

  >use 数据库名 // 这个指令也可以直接创建数据库,但只有添加数据后,

  show dbs 才能看到该数据库

查看当前数据库,默认数据库 :test

  >db

查看所有的数据集

  >show collections

删除当前数据库 操作 格式 实例 sql 中的类似语句

  等于 {:} db.collectionName.fifind({"by":"java"}).pretty()      相当于     where by = 'java'

  小于 {:{$lt:}} db.collectionName.fifind({"likes":{$lt:50}}).pretty()    相当于      where likes < 50

   小于或等于 {:{$lte:}} db.collectionName.fifind({"likes":{$lte:50}}).pretty()   相当于       where likes <= 50

  大于 {:{$gt:}} db.collectionName.fifind({"likes":{$gt:50}}).pretty()         相当于       where likes > 50

  大于或等于 {:{$gte:}} db.collectionName.fifind({"likes":{$gte:50}}).pretty()        相当于      where likes >= 50

  不等于 {:{$ne:}} db.collectionName.fifind({"likes":{$ne:50}}).pretty()            相当于    where likes != 50

创建集合(相当于创建表)


>db.createCollection("user1")

 

 

 


删除集合

>db.collectionName.drop()

集合重命名

>db.oldCollectionName.renameCollection("newName")

新增数据


>db.collectionName.insert({"key":value,"key":value})

>db.collectionName.save({"key":value,"key":value})


查询所有数据

>db.collectionName.find()

条件查询


> db.collectionName.find ({ "age" : 26 }) // 查询等值关系

> db.collectionName.find ({ age : {$ gt : 100 }}) // 大于 100

> db.collectionName.find ({ age : {$ gte : 100 }}) // 大于等于 100

> db.collectionName.find ({ age : {$ lt : 150 }}) // 小于 150

> db.collectionName.find ({ age : {$ lte : 150 }}) // 小于等于 150

> db.collectionName.find ({ age : {$ lt : 200 , $ gt : 100 }}) // 大于 100 ,小于 200


如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下


>db.collectionName.find().pretty()


and 关系

MongoDB 的 fifind() 方法可以传入多个键 (key) ,每个键 (key) 以逗号隔开,即常规 SQL 的 AND 条件

语法 :


>db.collectionName.find({key1:value1, key2:value2}).pretty()

or 关系



MongoDB OR 条件语句使用了关键字 $or , 语法格式如下:

语法 :

>db.collectionName.find({$or: [ {key1: value1}, {key2:value2}]}).pretty()

示例 :

>db.collectionName.find({$or:[{"by":"java"},{"title": "MongoDB 学习 "}]}).pretty()

清空集合数据

>db.collectionName.remove({}) // 条件删除 :remove({key:value})

// 删除满足条件的一条数据 :remove({key:value},1)

查询一条数据

>db.collectionName.findOne();

查询指定列

> db.collectionName.find ({},{ name : 1 , age : 1 , sex_orientation : true })

查询指定字段的数据,并去重

> db . collectionName . distinct ( 'sex' )

对结果集排序

> db.collectionName.find () .sort ({ salary : 1 }) // 升序

> db.collectionName.find () .sort ({ salary : -1 }) // 降序

统计记录数

> db .collectionName.find () .count ()

查询限定条数

>db.collectionName.find().limit(number)

使用 limit() 方法来读取指定数量的数据外,还可以使用 skip() 方法来跳过指定数量的数据, skip 方法同样

接受一个数字参数作为跳过的记录条数。


>db.collectionName.find().limit(NUMBER).skip(NUMBER)

更新数据

db.collectionName.update(<query>,<update>,{upsert: <boolean>, multi: <boolean>)


query: update 的查询条件

update : update 的对象和一些更新的操作符(如 $,$set... )等,也可以理解为 sql update 查询内 set 后面

upsert : 可选,如果不存在 update的记录,是否插入 objNew,true 为插入,默认是 false ,不插入。

multi : 可选, mongodb 默认是 false, 只更新找到的第一条记录,如果这个 参数为true,就把按条件查出 来多条记录全部更新。

示例 :


> db.collectionName.update({name: 'tom' },{ $set :{age:23}},false, true )





3 .Java调取mongoDB

第一步:添加mongodb-java-driver驱动包

<dependencies>

<dependency>

<groupId>org.mongodb</groupId>

<artifactId>mongo-java-driver</artifactId>

<version>3.2.2</version>

</dependency>

</dependencies>


第二步 : 连接数据库并操作数据


 


public static void main(String[] args) {

// 1. 连接到 mongodb 服务

MongoClient mongoClient = new MongoClient("192.168.197.133", 27017);

// 2. 连接到数据库

MongoDatabase mongoDatabase = mongoClient.getDatabase("mydb1");

//3. 创建集合

// mongoDatabase.createCollection("student");

// 获得集合

MongoCollection<Document> collection =

mongoDatabase.getCollection("users");

//4. 新增

Document document = new Document("stu1name", " 张三 ");

document.append("stu1age", 29);

document.append("sex", " 男 ");

collection.insertOne(document);

// 插入多行时,将 document 对象添加到 List 集合中,调取 insertMany()

//5. 获得所有文档

FindIterable<Document> documents = collection.find();

MongoCursor<Document> iterator = documents.iterator();


while (iterator.hasNext()) {

System.out.println(iterator.next());

}

//6. 更新文档 updateOne(),updateMany( 条件表达式,新值表达式 )

// collection.updateMany(Filters.eq("sex"," 男 "),new Document("$set",new

Document("name","testzhangsan")));

//7. 删除文档

// 删除 20 岁用户的信息

collection.deleteOne(Filters.eq("age",20));

}


 


 


4.mongDB索引

索引是对数据库表中一列或多列 的值进行排序的一种结构。

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个

文件并选取那些符合查询条件的记录。


4.1 创建索引的语法



  (1) 默认索引

MongoDB 有个默认的 “ id” 的键,相当于 主键 的角色。集合创建后系统会自动创建一个索引在 id”

键上,它是默认索引,索引名叫 “_id_” ,是无法被删除的。我们可以通过以下方式查看:

>db.collectionName.getIndexes()

(2) 单列索引

在单个键上创建的索引就是单列索引,例如我们要在 Users 集合上给 title 键创建一个单列索引,语

法如下:

( 1 表示正序, -1 逆序)


>db.collectionName.createIndex({"title":1})


(3) 组合索引

另外,我们还可以同时对多个键创建组合索引。如下代码创建了按照 “UserId” 正序, “UserName”

逆序的组合索引 :


>db.collectionName.createIndex({"userid":1,"username":-1})

(4) 唯一索引

唯一索引限制了对当前键添加值时,不能添加重复的信息。值得注意的是,当文档不存在指定键

时,会被认为键值是 “null” ,所以 “null” 也会被认为是重复的,所以一般被作为唯一索引的键,最好都要

有键值对。

对 “UserId” 创建唯一索引 ( 这时候最后一个参数为 “true”) :


>db.collectionName.createIndex({"UserId":1}, { unique: true });


(5)TTL 索引

TTL 指生命周期的意思。即存储的 document 存储带有过期时间属性,超过生命周期自己主动删除。

像日志数据、系统自己主动产生的暂时数据、会话数据等均符合这一场景。

构建方式如:


db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 }

) (6) 删除索引

新手常陷入的误区是,认为集合被删除,索引就不存在了。关系型数据库中,表被删除了,索引也

不会存在。在 MongoDB 中不存在删除集合的说法,就算集合数据清空,索引都是还在的,要移除索引

还需要手工删除。

>db.collectionName.dropIndexes()

删除集合指定索引

>db.collectionName.dropIndex(" 索引名称 ")

说明 :drop() 集合时,索引也会删除, remove() 集合时,索引仍然存在

 


 

5 .mongoDB备份与恢复

5.1 mongodump命令来备份数据

该命令可以导出所有数据到指定目录中。

mongodump 命令可以通过参数指定导出的数据量级转存的服务器。

语法

>mongodump -h dbhost -d dbname -o dbdirectory

-h :

MongDB 所在服务器地址,例如: 127.0.0.1 ,当然也可以指定端口号: 127.0.0.1:27017

-d :

需要备份的数据库实例,例如: test

 

l--o  备份的数据存放位置,例如: c:\data\dump ,当然该目录需要提前建立,在备份完成后,系统自

动在 dump 目录下建立一个 test 目录,这个目录里面存放该数据库实例的备份数据。

示例

在本地使用 27017 启动你的 mongod 服务。打开命令提示符窗口,进入 MongoDB 安装目录的 bin 目录

  输入命令   > mongodump:   (不指定在当前目录保存)

  执行以上命令后,客户端会连接到 ip 为 127.0.0.1 端口号为 27017 的 MongoDB 服务上,并备份所有数

  据到 bin/dump/ 目录中。命令输出结果如下:


5.2 MongoDB 数据恢复


mongodb 使用 mongorestore 命令来恢复备份的数据。

语法


   >mongorestore -h <hostname><:port> -d dbname <path>

 


   --host <:port>, -h <:port> :

MongoDB 所在服务器地址,默认为: localhost:27017

   --db , -d :

需要恢复的数据库实例,例如: test ,当然这个名称也可以和备份时候的不一样,比如 test2

   --drop :

恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都

会被删除,慎用哦!

6 集群搭建

  集群搭建方式之一就是mongoDB复制集,即一组mongod的进程。他们维护同一个数据集合。复制集

保证了数据的可靠性和高读取能力。

6.1 机制

  一组复制集就是一组 mongod 实例管理同一个数据集,实例 key 在不同的机器上,实例包含主实例

(primary), 接受所有的写操作,其他的属于副本实例 (Secondary), 从服务器保持与主服务器数据同步,类

似于 redis 中的主从复制。

每个复制集还有一个仲裁者 (Arbiter), 仲裁者的任务就是通过心跳机制来确认集群中集合的数量,并

在选举主服务器的过程中进行裁决。仲裁者并不存储数据,性质等价于 redis 中的哨兵机制。

mongodb必会知识点_nosql_03

8.2 架构

  在数据承载节点中,一个且只有一个成员被视为主节点,而其他节点则被视为辅助节点。节点接收所有

  写入操作,一个副本集只能有一个主实例能够写入,主节点记录所有变更到它的记录 辅助节点复制主节点的 oplog 并将操作应用于数据集。

  仲裁员不维护数据集,仲裁器的目的是通过响应其 他副本集成员的心跳和选择请求来维护副本集中的仲裁。

  因为它们不存储数据集,所以仲裁器是提供副本集仲裁功能的一种好方法。

   与具有数据集的完全功能副本集成员相比,仲裁器的资源成本更低,如果副本集的成员数为偶数,则添

  加一个仲裁器以在初选中获得多数票。

  当一个主服务器在超过配置的周期(默认为 10 秒)内未与该组的其他成员通信时,符合条件的辅助服

务器将要求选择将其自身指定为新的主服务器。集群试图完成新的初选并恢复正常操作。

8.3 搭建步骤

(1) 准备三台虚拟机服务器,并各自安装好 mongoDB

注:为了保证复制集中三个服务器之间正常连接,请保证三个服务器的防火墙都已关闭!

  192.168.132:27017

  192.168.133:27017

  192.168.134:27017

(2) 修改 mongodb.conf 文件,添加 replSet 配置 ( 三台都需要修改成同一个名称 ) ,然后启动服务器


     replSet=rep1

(3) 初始化复制集


登录任意一台执行初始化操作

说明 : _id 指复制集名称, members 指复制集服务器列表,数组中的 _id 是服务器唯一的 id,host 服务器主

机 ip


# 复制集名称

     rs.initiate({_id:'rep1',members:[{_id:1,host:'192.168.197.132:27017'},

       {_id:2,host:'192.168.197.133:27017'},{_id:3,host:'192.168.197.134:27017'}]})


(4) 查看集群状态

(5) 测试


# 添加数据

    db.users.insert({"name":"lisi","age":11})

# 查询数据

    db.users.find()

# 切换到从数据库查询数据

如果不允许查询,是因为默认情况下从数据库是不允许读写操作的,需要设置。

    >rs.slaveOK()

执行该命令后可以查询数据

 

 

 

 


(6) 测试复制集主从节点故障转移功能


# 关闭主数据库 , 注意从数据库的变


     >db.shutdownServer()

(7) 主复制集添加仲裁者 (arbiter)

  现在我们的环境是一主两从,仲裁者对偶数集群有效。需要停止一个从机,在主服务器中运行下面命令

  在一主一从关系中,任意节点宕机都无法选举出主节点,无法提供写操作,此时需要加入仲裁者节点即 可。

         rs.remove("ip: 端口号 ") // 删除从节点


  在一主一从关系中,任意节点宕机都无法选举出主节点,无法提供写操作,此时需要加入仲裁者节点即 可。


        rs.addArb("ip: 端口号 ")



 

累,点个赞可否 么么哒~

~拜了个拜