必备面试题之 - MongoDB面试题

分类: 互联网 > 面试题

1、mongodb简介

1)MongoDB 更类似 MySQL,支持字段索引、游标操作,其优势在于查询功能比较强大,擅长查询 JSON 数据, 能存储海量数据,但是不支持事务

2)MySQL 在大数据量时效率显著下降,MongoDB 更多时候作为关系数据库的一种替代。

3)Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它 支持多种类型的数据结构,如 字符串(strings), 散列(hashes),列表(lists), 集合(sets), 有序集 合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务 (transactions) 和不同级别的 磁盘持久化(persistence),并通过 Redis哨兵(Sentinel)和自动 分区 (Cluster)提供高可用性(high availability)

2、Redis和MongoDB的区别

之前也用过redis,当时是用来存储一些热数据,量也不大,但是操作很频繁。现在项目中用的是MongoDB,目前是百万级的数据,将来会有千万级、亿级。

就Redis和MongoDB来说,大家一般称之为Redis缓存、MongoDB数据库。这也是有道有理有根据的:

    Redis主要把数据存储在内存中,其“缓存”的性质远大于其“数据存储“的性质,其中数据的增删改查也只是像变量操作一样简单;

    MongoDB却是一个“存储数据”的系统,增删改查可以添加很多where条件,就像SQL数据库一样灵活

        1)内存管理机制

        Redis 数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的 LRU 算法删除数据。 MongoDB 数据存在内存,由 linux系统 mmap 实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。

        2)支持的数据结构

        Redis 支持的数据结构丰富,包括hash、set、list等。 MongoDB 数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。

        3)数据量和性能:

        当物理内存够用的时候,redis>mongodb>mysql 当物理内存不够用的时候,redis和mongodb都会使用虚拟内存。 实际上如果redis要开始虚拟内存,那很明显要么加内存条,要么你换个数据库了。 但是,mongodb不一样,只要,业务上能保证,冷热数据的读写比,使得热数据在物理内存中,mmap的交换较少。 mongodb还是能够保证性能。

        4)性能

        mongodb依赖内存,TPS较高;Redis依赖内存,TPS非常高。性能上Redis优于MongoDB。

        5)可靠性

        mongodb从1.8版本后,采用binlog方式(MySQL同样采用该方式)支持持久化,增加可靠性;Redis依赖快照进行持久化;AOF增强可靠性;增强可靠性的同时,影响访问性能。可靠性上MongoDB优于Redis。

        6)数据分析

        mongodb内置数据分析功能(mapreduce);而Redis不支持。

        7)事务支持情况

        Redis 事务支持比较弱,只能保证事务中的每个操作连续执行;mongodb不支持事务。

        8)集群

        MongoDB 集群技术比较成熟,Redis从3.0开始支持集群。 

3、MongoDB命令

1)连接:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

2)查看 / 创建 / 删除 数据库

show dbs // 查看所有数据库
use DATABASE_NAME // 创建数据库
use DATABASE_NAME; db.dropDatabase() // 切换到当前数据库,并执行删除命令

3)查看 / 创建 / 删除 集合

show colletctions // 查看集合
db.createCollection(name, options) // 创建集合【option:capped-true:固定大小的集合,size:集合的字节数 max:集合的最大文档数,在插入文档时,先检查size,再检查max】
db.name.drop() // 删除集合

4)插入文档

db.name.insert({}) // 插入数据
db.name.insertOne({}) // 插入单条数据
db.name.insertMary([{}, {}]) // 插入多条数据
db.name.replaceOne({}) // _id存在则更新,否则是新增

5)更新文档

db.name.update({query}, {update}, {option}) // multi:更新多条,默认一条,update:操作符:$set 更新 $inc 递增

6)删除文档

db.name.remove({query}, {option}) // justOne:是否只删除一条,默认删除所有

7)查询文档

db.name.find({query}, {projection}) // 查询文档,projection 查询字段
db.name.findOne({query}, {projection}) // 查询文档,只返回第一条
db.name.find().pretty() // 查询文档-格式化

8)条件操作符

{<key>:<value>} // 等于
{<key>:{$lt:<value>}} // $lt 小于 $lte 小于或等于 $gt 大于 $gte 大于或等于 $ne 不等于
{key1:value1, key2:value2} AND条件
{$or: [{key1:value1}, {key2:value2}]} OR条件

9)$type 操作符

{<key>:{$type: <type>}} 
1: Double
2: String
3: Object|
4: Array
5: Binary data
7: Object_id
8: Boolean
9: Date
10: Null
11: Regular Expression
13: Javascript
14: Symbol
15: Javascript(with scope)
16: 32-bit integer
17: Timestamp
18: 64-bit integer
255: Min key
127: Max key

10)limit 与 skip 方法

db.name.find().limit(number) // number 限制的数量
db.name.find().skip(number) // number 跳过的记录数 

11)sort 排序

db.name.find().sort({<key>: 1}) // 按照key字段排序,1为升序排列 -1为降序排列

12)建立索引:索引存储在一个易于遍历读取的数据集合中

db.name.createIndex({<key>: 1}, options) // 以key字段建立索引,1为升序建立索引,可多个字段建立复合索引
// options:background-是否以后台形式建立索引,默认false; unique-唯一索引; name-索引名称 expireAfterSeconds-设定集合的生存时间
db.name.getIndexes() // 获取索引集合
db.name.totalIndexSize() // 获取集合索引大小
db.name.dropIndexs() // 删除所有索引
db.name.dropIndex("索引名称") // 删除单个索引

13)聚合:主要用于处理数据(如统计、平均值),并返回计算后的结果

db.name.aggregate(<operation>)
分组并计算:{[{$group: {"_id": "$字段", <显示名称>: {<计算方法>: {$字段}}}}]} // $sum-计算总和 $avg-计算平均值 $min-最小值 $max-最大值 $push-将值加入新数组 $addToSet-将值加入新数组,会判断是否重复 $frist 获取第一个文档 $last 获取最后一个文档

管道的概念:

$project: 修改输入文档的结构。可以用来重命名、增加或者删除域,也可以用于创建计算结果以及嵌套文档
$match: 用于过滤数据,只输出符合条件的文档
$limit: 用于限制MongoDB聚合管道返回的文档数
$skip: 在聚合管道中跳过指定数量的文档,并返回余下的文档
$unwind: 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果
$sort:将输入文档排序后输出
$geoNear:输出接近某一地理位置的有序文档

4、MongoDB复制(副本集)

MongoDB复制是讲数据同步到多个服务器的过程。

复制提供了数据的荣誉备份,并在多个服务器上存储数据副本,提高了数据的可用性,并保证了数据的安全性

复制还允许您从硬件故障和服务中断中恢复数据

复制的优点

    1)保障数据的安全性

    2)数据高可用性(24 * 7)

    3)灾难恢复

    4)无需停机维护(如备份,重建索引,压缩)

    5)分布式读取数据

复制的原理

    1)mongoDB的复制至少需要两个节点,其中一个是主节点,负责处理客户端请求,其余都是从节点,负责复制主节点上的数据

    2)mongoDB各个节点常见的搭配方式为:一主一从、一主多从

    3)主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致

副本集特征:

    1)N个节点的集群

    2)任何节点可作为主节点

    3)所有写入操作都在主节点上

    4)自动故障操作

    5)自动恢复

5、MongoDB分片

在mongoDB里面存在另一种集群,就是分片技术,可以满足mongoDB数量大量增长的需求

当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时候我们可以通过在多台机器分割数据,使得数据库系统能存储和处理更多的数据

为什么使用分片:

    1)复制所有的写入操作到主节点

    2)延迟的敏感数据会在主节点查询

    3)单个副本集限制在12个节点

    4)当请求量巨大时会出现内存不足

    5)本地磁盘不足

    6)垂直扩展价格昂贵

分片有三个主要组件:

    1)Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障

    2)Config Server:mongo实例,存储了整个ClusterMetadata,其中包括chunk信息

    3)Query Routes:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用


来源:原创 发布时间:2022-06-06 11:49:10