MongoDB是目前最好的面向文档的免费开源NoSQL数据库。如果你正准备参加MongoDB NoSQL数据库的技术面试,你最好看看下面的MongoDB NoSQL面试问答。这些MongoDB NoSQL面试问答涵盖了NoSQL数据库基本的概念,复制(Replication),分片(Sharding),事务和锁,跟踪分析工具 (Profiler),Nuances和日志等特性。让我们看看下面的这些MongoDB NoSQL数据库的面试问答吧:
1. 你说的NoSQL数据库是什么意思?NoSQL与RDBMS直接有什么区别?为什么要使用和不使用NoSQL数据库?说一说NoSQL数据库的几个优点?
我写了一篇完整的博客来回答这些问题,看这里
A) NoSQL: Not Only SQL 的缩写,它的意思是:使用关系型数据库的时候就用关系型数据库,不适用的时候也没有必要使用关系型数据库不可以,可以考虑使用更加适合的数据存储.
B) RDBMS:关系型数据库管理系统,它的特点是:
数据以表格的形式出现
每行为各种记录名称
每列为各种记录名称所对应的数据项
许多行和列组成一张表单
若个表组成一个database
NoSQL:非关系型数据库,它发展的原因是互联网web2.0网站的兴起,特别是超大规模和高并发的SNS类型的纯动态网站已经显得力不从心,暴露出很多难以克服的问题才发展出来的,例如
对数据库高并发读写的需求
对数据库的高可扩展性和高可用性的需求
对海量数据的高校存储和访问的需求
NoSQL的特性:
可以处理超大量的数据
运行在便宜的PC服务器集群上
击碎了性能瓶颈------通过NoSQL架构可以省去将Web或Java应用和数据转换成SQL友好格式的时间,执行速度更快.
没有过多的操作
NoSQL的优点:
易扩展性---去掉了关系数据库的关系特性,数据之间无关系,非常容易扩展
大数据量,高性能-----NoSQL数据库都有非常高的读写能力,尤其在大数据量下,,同样表现优秀,这得益于他的无关系性,数据库的结构简单,一般 MySQL使用Query Cache,每次表的跟新Cache就失效,是一种大粒度的Cache,在针对Web2.0的交互频繁的应用,Cache性能不高,而NoSQL的 Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说急剧要性能高多了.
灵活的数据模型---NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式.
高可用性------NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构,比如Cassandra,HBase模型,通过复制模型也能实现高可用性.
C) 关系行数据库的优势
保持数据的一致性(事务处理)
由于以标准作为前提,数据更新的开销很小(相同的字段基本都只有一处)
可以进行JOIN等复杂查询
存在很多实际成果和专业技术信息
D) NoSQL的应用场景:
希望顺畅地对数据进行缓存(Cache)处理
希望对数组类型的数据进行高速处理
希望进行全保存
NoSQL数据库有哪些类型?
NoSQL数据库有三种类型
键值存储
它的数据以键值的形式存储,虽然它的处理速度非常快,但是基本上只能通过键的完全一致查询获取数据,根据数据的保存方式可以分为临时性,永久性和两者兼具三种.
临时性
Memcached
在内存中保存数据
可以进行非常快速的保存和读取处理
数据可能丢失
c) 永久性
在硬盘上保存数据
可以进行非常快的保存和读取处理(但无法和memcached相比)
数据不会丢失
d) 两者兼具
Redis
Redis首先把数据保存到内存中,在满足特定的条件的时候将数据写入到硬盘上,这样既确保了内存中数据的处理速度,又可以通过写入硬盘来保证数据的永久性,这种类型的数据库特别适合处理数组类型的数据.
面向文档的数据库
MongoDB, CouchDB
不定义表结构
可以使用复杂的查询条件----面向文档的数据库可以通过复杂的查询条件来获取数据,虽然不具备事务处理和JOIN这些关系型数据库所具有的处理能力,但除此之外的其他处理基本上都能实现.
面向列的数据库
Cassandra, HBase
以列为单位来存储数据
对大量行少数列进行读取,对所有行的特定列进行同时更新
高扩展性(特别是写入速度)
应用十分困难
3. MySQL与MongoDB之间最基本的差别是什么?
MySQL 和MongoDB两者都是免费开源的数据库。MySQL和MongoDB有许多基本差别包括数据的表示(data representation),查询,关系,事务,schema的设计和定义,标准化(normalization),速度和性能。通过比较MySQL 和MongoDB,实际上我们是在比较关系型和非关系型数据库。
NoSQL与关系型数据库设计理念比较
关系型数据库中的表都是存储一 些格式化的数据结构,每个元祖字段的组成都一样,即使不是每个元祖都需要所有的字段,但是数据库会为每个元祖分配所有的字段,这样的结构可以便于表与表之 间进行连接等操作,但从另一个角度来说它也是关系型数据库性能瓶颈的一个因素,而非关系型数据库以键值对存储,它的结构不固定,每个元祖可以有不一样的字 段,每一个元祖可以根据需要增加一些自己的键值对,这样就不会局限于固定的结构,可以减少一些时间和空间的开销.
4. 你怎么比较MongoDB、CouchDB及CouchBase?
MongoDB和CouchDB都是面向文档的数据库。MongoDB和CouchDB都是开源NoSQL数据库的最典型代表。 除了都以文档形式存储外它们没有其他的共同点。MongoDB和CouchDB在数据模型实现、接口、对象存储以及复制方法等方面有很多不同。
细节可以参见下面的链接:
MongDB vs CouchDBCouchDB vs CouchBase
5. MongoDB成为最好NoSQL数据库的原因是什么?
以下特点使得MongoDB成为最好的NoSQL数据库:
面向文件的,丰富的数据模型
容易扩展
不牺牲速度
便捷的管理
丰富的查询语言
6.32位系统上有什么细微差别?
journaling会激活额外的内存映射文件。这将进一步抑制32位版本上的数据库大小。因此,现在journaling在32位系统上默认是禁用的。
7. journal回放在条目(entry)不完整时(比如恰巧有一个中途故障了)会遇到问题吗?
每个journal (group)的写操作都是一致的,除非它是完整的否则在恢复过程中它不会回放。
8. 分析器在MongoDB中的作用是什么?
MongoDB中包括了一个可以显示数据库中每个操作性能特点的数据库分析器。通过这个分析器你可以找到比预期慢的查询(或写操作);利用这一信息,比如,可以确定是否需要添加索引。
9. 名字空间(namespace)是什么?
MongoDB存储BSON对象在丛集(collection)中。数据库名字和丛集名字以句点连结起来叫做名字空间(namespace)。
10. 如果用户移除对象的属性,该属性是否从存储层中删除?
是的,用户移除属性然后对象会重新保存(re-save())。
11. 能否使用日志特征进行安全备份?
是的。
12. 允许空值null吗?
对于对象成员而言,是的。然而用户不能够添加空值(null)到数据库丛集(collection)因为空值不是对象。然而用户能够添加空对象{}。
13. 更新操作立刻fsync到磁盘?
不 会,磁盘写操作默认是延迟执行的。写操作可能在两三秒(默认在60秒内)后到达磁盘。例如,如果一秒内数据库收到一千个对一个对象递增的操作,仅刷新磁盘 一次。(注意,尽管fsync选项在命令行和经过getLastError_old是有效的)(译者:也许是坑人的面试题??)。
14. 如何执行事务/加锁?
MongoDB没有使用传统的锁或者复杂的带回滚的事务,因为它设计的宗旨是轻量,快速以及可预计的高性能。可以把它类比成MySQL MylSAM的自动提交模式。通过精简对事务的支持,性能得到了提升,特别是在一个可能会穿过多个服务器的系统里。
15. 为什么我的数据文件如此庞大?
MongoDB会积极的预分配预留空间来防止文件系统碎片。
16. 启用备份故障恢复需要多久?
从 备份数据库声明主数据库宕机到选出一个备份数据库作为新的主数据库将花费10到30秒时间。这期间在主数据库上的操作将会失败--包括写入和强一致性读取 (strong consistent read)操作。然而,你还能在第二数据库上执行最终一致性查询(eventually consistent query)(在slaveOk模式下),即使在这段时间里。
17. 什么是master或primary?
它是当前备份集群(replica set)中负责处理所有写入操作的主要节点/成员。在一个备份集群中,当失效备援(failover)事件发生时,一个另外的成员会变成primary。
18. 什么是secondary或slave?
Seconday从当前的primary上复制相应的操作。它是通过跟踪复制oplog(local.oplog.rs)做到的。
19. 我必须调用getLastError来确保写操作生效了么?
不用。不管你有没有调用getLastError(又叫"Safe Mode")服务器做的操作都一样。调用getLastError只是为了确认写操作成功提交了。当然,你经常想得到确认,但是写操作的安全性和是否生效不是由这个决定的。
20. Should I start out with sharded or with a non-sharded MongoDB environment? 我应该启动一个集群分片(sharded)还是一个非集群分片的 MongoDB 环境?
为 开发便捷起见,我们建议以非集群分片(unsharded)方式开始一个 MongoDB 环境,除非一台服务器不足以存放你的初始数据集。从非集群分片升级到集群分片(sharding)是无缝的,所以在你的数据集还不是很大的时候没必要考虑 集群分片(sharding)。
21. 分片(sharding)和复制(replication)是怎样工作的?
每一个分片(shard)是一个分区数据的逻辑集合。分片可能由单一服务器或者集群组成,我们推荐为每一个分片(shard)使用集群。
22. 数据在什么时候才会扩展到多个分片(shard)里?
MongoDB 分片是基于区域(range)的。所以一个集合(collection)中的所有的对象都被存放到一个块(chunk)中。只有当存在多余一个块的时候, 才会有多个分片获取数据的选项(Only when there is more than 1 chunk is there an option for multiple shards to get data.)。现在,每个默认块的大小是 64Mb,所以你需要至少 64 Mb 空间才可以实施一个迁移。
23. 当我试图更新一个正在被迁移的块(chunk)上的文档时会发生什么?
更新操作会立即发生在旧的分片(shard)上,然后更改才会在所有权转移(ownership transfers)前复制到新的分片上。
24. 如果在一个分片(shard)停止或者很慢的时候,我发起一个查询会怎样?
如果一个分片(shard)停止了,除非查询设置了“Partial”选项,否则查询会返回一个错误。如果一个分片(shard)响应很慢,MongoDB则会等待它的响应。
25. 我可以把moveChunk目录里的旧文件删除吗?
没问题,这些文件是在分片(shard)进行均衡操作(balancing)的时候产生的临时文件。一旦这些操作已经完成,相关的临时文件也应该被删除掉。但目前清理工作是需要手动的,所以请小心地考虑再释放这些文件的空间。
26. 我怎么查看 Mongo 正在使用的链接?
db._adminCommand("connPoolStats");
27. 如果块移动操作(moveChunk)失败了,我需要手动清除部分转移的文档吗?
不需要,移动操作是一致(consistent)并且是确定性的(deterministic);一次失败后,移动操作会不断重试;当完成后,数据只会出现在新的分片里(shard)。
28. 如果我在使用复制技术(replication),可以一部分使用日志(journaling)而其他部分则不使用吗?
可以。