NoSQL数据存储让数据管理方式更加灵活,彻底改变了软件开发的状况。MongoDB是知名的NoSQL解决方案之一,这是一种面向文档的数据存储系统。本文探讨MongoDB是什么以及它如何满足您的应用需求。 |
MongoDB:文档数据存储系统
关系数据库将信息存储在严格监管的表和列中。MongoDB是一种文档存储系统,将信息存储在集合和文档中。这里的主要区别在于集合和文档是非结构化的,有时称为无模式。这意味着MongoDB实例(集合和文档)的结构不是预定义的,可灵活适应放入其中的任何数据。
文档是一个键值集,其行为与JavaScript等代码中的对象非常相似:它的结构根据放入其中的数据而变化。这使得针对MongoDB等数据存储系统进行编程比针对关系数据存储系统进行编程来得更容易、更灵活。简而言之,应用程序代码和文档数据存储系统之间的交互感觉更自然。
图1直观地显示了MongoDB数据库、集合和文档的结构。
这种类型的数据建模继承的灵活性意味着可以在更加按需使用的基础上处理数据,从而实现此处所述的性能优势。
想具体了解这种差异,不妨比较以下两种实现相同任务(创建记录,然后从应用程序添加字段)的方法,先用关系数据库,之后用MongoDB。
关系数据库中的步骤:
# create a database: CREATE DATABASE menagerie; # create a table in the database: USE menagerie; CREATE TABLE pet (name VARCHAR(20)); # connect to the database in app and issue insert: INSERT INTO pet (name) VALUES ('Friar Tuck'); # add a column: ALTER TABLE pet ADD type VARCHAR(20)); # update existing record: UPDATE pet SET type = 'cat' WHERE name = 'Friar Tuck'
现在用MongoDB执行同样的过程:
# connect to the database in app and issue insert: use menagerie; db.pet.insertOne({name:"friar tuck"}); # issue update: db.pet.updateOne({ name:'friar tuck' }, { $set:{ type: 'cat' } } );
从前面您可以了解使用MongoDB的开发体验有多流畅。
这种灵活性当然将避免模式臃肿的负担加在了开发人员的身上。驾驭大型应用程序的文档结构至关重要。
MongoDB中的ID字段
关系型数据库中有主键这个概念,这通常是一个合成ID列(也就是说,与业务数据无关的生成值)。在MongoDB中,每个文档都有一个用途相似的_id字段。如果开发人员在创建文档时没有提供 ID,MongoDB引擎将自动生成一个ID(作为 UUID)。
与主键一样,_id 字段自动索引,而且必须是唯一的。
MongoDB中的索引
MongoDB中的索引其行为类似关系数据库中的索引:它创建有关文档字段的额外数据,以加快依赖该字段的查询。MongoDB使用 B 树索引。
可以使用如下语法创建索引:
db.pet.createIndex( { name: 1 } )
参数中的整数表示索引是升序(1) 还是降序(-1)。
MongoDB中嵌套文档
MongoDB面向文档结构的一个强大方面是文档可以嵌套。比如说,您可以创建嵌套文档,而不是创建另一个表来存储宠物文档的地址信息,结构如代码片段1所示。
代码片段1. 嵌套文档示例
{ "_id": "5cf0029caff5056591b0ce7d", "name": "Friar Tuck", "address": { "street": "Feline Lane", "city": "Big Sur", "state": "CA", "zip": "93920" }, "type": "cat" }
MongoDB中的非规范化
MongoDB等文档存储系统对连接的支持有限,也没有外来键的概念。两者都是数据结构动态特性的结果。MongoDB中的数据建模倾向于非规范化,即复制文档中的数据,而不是将数据严格保存在表孤岛中。这提高了查找速度,不过以增加数据一致性维护为代价。
非规范化不是必需的,在使用面向文档的数据库时更多地是一种倾向。这是由于处理复杂嵌套记录的能力得到了提高,而不是SQL倾向于将数据规范化到特定的单值列中。
MongoDB查询语言
MongoDB中的查询语言面向JSON,就像文档结构一样。这有助于一种非常强大的表达式语法,甚至可以处理复杂的嵌套文档。
比如说,您可以通过执行db.pet.find({ "type" : "cat" })来查询收录所有猫咪的理论数据库,或使用db.pet.find({ "type" : "cat" , "address.state": "CA" })来查询加利福尼亚州的所有猫咪。请注意,查询语言遍历嵌套的地址文档。
MongoDB更新语法
MongoDB的alter语法也使用类似JSON的格式,其中$set关键字表明将更改哪个字段、更改为什么值。set对象通过点表示法支持嵌套文档,如代表片段2所示,可以在其中更改名为“Friar Tuck”的那只猫的邮政编码。
代码片段2. 更新嵌套文档
db.people.update( { "type": "cat", "name": "Friar Tuck" }, { $set: { "address.zip": "86004" } } )
可以从代码片段2中看到,更新语法与SQL对应语法一样强大,实际上更强大。
MongoDB云和部署选项
MongoDB为可扩展性和分布式部署而设计。它完全能够处理大规模工作负载。
MongoDB公司在MongoDB Atlas中提供了多云数据库集群解决方案。MongoDB Atlas就像一个托管数据库,可以横跨不同的云平台,包括监控和容错等企业功能。
不难看出MongoDB的重要性,因此AWS的Amazon DocumentDB产品将MongoDB兼容性作为主要卖点。微软的Azure Cosmos DB遵循类似的模式,支持MongoDB API。
MongoDB中的高可用性
MongoDB支持副本集以实现高可用性。核心思想是将数据一次写入主实例,然后复制到二级存储以便读取。在此处(https://docs.mongodb.com/manual/replication/)可了解有关MongoDB中复制的更多信息。
结论是,MongoDB是一种领先的 NoSQL 解决方案,兑现了灵活模式数据存储系统的承诺。可使用面向几乎各种编程语言的高级驱动程序,您也可以利用众多部署选项。