有专门的SQL背景的人钻研NoSQL看起来是一项艰巨的任务。我曾经在小型MySQL环境和大型Oracle SQL环境使用过SQL。下面就从一个SQL用户的角度来看看MongoDB的优势、弱点、特性和使用。
MongoDB在什么时候是一个不错的选择?
MongoDB是一个令人难以置信地健壮的、可扩展的、操作简便的数据库解决方案。 MongoDB是一个不错的选择,当你的开发者也需要负责数据库环境时。在小商店和创业公司,可能就是这样。 MongoDB用BSON (二进制JSON)存储信息。BSON是MongoDB用来检索存储在后端的BSON的信息的原生的JSON(JavaScript对象符号)语言。JSON和其他编程语言看起来很相近,许多开发者已经有过使用它的经验了。
当你需要大量写操作时,MongoDB同样是个不错的选择。这不是说当处理写任务繁重(write-heavy) 环境时MySQL没有好的选择,但是MongoDB处理起来相对轻松一点。Facebook为写任务繁重的环境设计了RocksDB存储引擎,也能很好地运行(标准检查程序测试证明了这一点)。
当你需要一个无模式(schemaless)或者模式灵活(schema-flexible)的数据结构的时候,MongoDB是一个不错的选择。 MongoDB能够相对轻松和优雅地处理你的数据组织的更改。这是NoSQL解决方案的卖点。MySQL世界也做了很多改进,使得在线模式(schema)更改成为可能,但是仍然比不上MongoDB那么简单。不需要定义结构就能创建记录的机制给MongoDB增加了灵活性。
选择MongoDB的另一个原因是它关于副本集设置、内置分片(build-in sharing)和自动选举主数据集(auto elections)的功能。在MongoDB搭建副本环境是很简单的,而且如果主节点(primary)挂了,自动选举主数据库过程允许一个第二主节点(secondary)接管主节点的职责。内置分片允许简单的水平扩展,对于MySQL环境来说管理、搭建和配置水平扩展都更加复杂。
什么时候你应该选择其他数据库?
MongoDB在某些情况下是一个很好的选择。在其他的某些情况下它又不是一个好的选择了。当你的数据高度关联和结构化时,MongoDB可能不是一个正确的选择。MongoDB不支持事务,但是在文档层面上,它的文档是原子性的。有关write concern机制的副本环境配置需要考虑一些问题,但解决这些问题是要以性能为代价的。 write concern异常的出现证明副本节点已经写入了信息。默认地,MongoDB设置了write concern只从主节点请求确认,而不从副本节点做这个事情。如果副本节点出现问题,这可能会导致违反数据一致性的情况。
MongoDB和MySQL在结构上有什么区别?
在SQL世界的许多概念听起来很像MongoDB的文档结构。让我们看一下一个简单的MongoDB环境的高层结构来更好地理解是怎么布局的。
下面的图表把MySQL和MongoDB做了一个关联(这是在MongoDB的官方文档发现的)。
另一个有趣的值得注意的地方是mongod进程。这是一个处理数据请求的守护进程,和MySQL的mysqld进程非常相似。这个进程监听MongoDB请求,管理数据库的访问。和MySQL一样,mongod进程也有一些启动选项。最重要的配置选项之一是—— 指定你的mongod实例使用的一个配置文件的配置。MySQL有轻微不同的是,这个文件使用YAML格式。下面是MongoDB的一个示例配置文件。请注意这个文件只是为了演示格式而已。它没有对用于生产的数据库做任何优化。
从定义上来说,MongoDB是一个文档存储数据库。这个图表可以让你对MongoDB的数据结构与MySQL或任何SQL风味数据库的关联有一些概念。不同于建一个表和添加数据,你可以在不定义数据结构的情况下直接插入数据到一个collection。这是MongoDB在灵活性上超过MySQL的优点之一。只是因为MongoDB提供了它的灵活性并不意味着组织一个功能强大的应用于生产的MongoDB数据库是毫不费力的,注意到这点很重要。和选择任何数据库一样,你应该留心数据库的数据结构和要达到的目标,来避免迟早会掉入的陷阱。
注意:YAML格式不处理标签。使用空格来缩进吧。
查询方面有什么差别?
通过shell和数据库进行交互方面,MongoDB的使用也和SQL有些差别。MongoDB用JSON来进行查询。同样,web开发人员对此非常熟悉,这也是吸引人们使用MongoDB的其中一个原因。下面是一个从SQL翻译过来成MongoDB用语的查询。我们有一个表user,这个表里面只有username和对应的ID。
用SQL来查询:
select username from user where id = 2;
在MongoDB里面的查询:
db.user.find({_id:2},{“username”:1})
我们以JSON格式指定了查询的user集合(collection)和我们感兴趣的文档的ID。最后,我们想要从其获得值的字段被指定。查询的结果将会是ID为2的用户(user)的用户名(username)。
总结
MongoDB对于你的MySQL困境来说并不是一个新技术了。 随着这两个数据库的不断发展,他们的弱点和优势开始慢慢地融合在了一起。不要让MongoDB灵活的数据结构欺骗你,让你认为你不需要对你的数据环境做好计划。这在未来一定会导致让你头痛的事情。这种灵活性允许的是动态的,快速的变化——而不是轻率的变化。
我鼓励任何MySQL用户为了测试的目的去获取一个MongoDB实例。在电子商务和游戏的世界,MongoDB是一个热门的选项,这得益于它的模式(schema)设计灵活性和对大量数据进行水平扩展的功能。