MongoDB 从入门到放弃
什么是 mongoDB
MongoDB 是一种非关系型数据库(NoSQL),它以文档为基本存储单位,支持动态查询和索引,是一种面向文档的数据库管理系统。
与传统的关系型数据库不同,MongoDB 不需要固定的表结构,也不需要预定义的字段。每个文档都是一个独立的实体,可以存储不同结构和类型的数据。这种灵活性使得 MongoDB 非常适合处理非结构化数据,如日志、社交媒体、IoT 数据等。
MongoDB 的主要特点包括:
-
高性能:MongoDB 具有快速的读写性能,可进行高度可扩展的数据存储和查询。
-
高可用性:MongoDB 支持自动故障转移和数据复制,可在多个服务器之间实现高可用性和可靠性。
-
高扩展性:MongoDB 可以在不断增长的数据集上运行,支持垂直和水平扩展。
-
灵活性:MongoDB 支持非常灵活的数据模型,可以存储不同结构和类型的数据。
-
开源免费:MongoDB 是一款开源软件,可以免费使用和修改。
MongoDB 使用 JSON 格式存储数据,支持 ACID 事务,还支持全文索引、地理空间索引等高级功能。它可以与许多编程语言和工具集成,如 Python、Java、Node.js 等,非常适合开发 Web 应用程序和大规模数据处理项目。
与传统 SQL 的区别
MongoDB 和传统的 SQL 数据库在数据存储和查询上有很大的区别。
-
数据模型:MongoDB 是文档型数据库,使用 BSON 格式存储数据。SQL 数据库则使用表格模型,将数据分解为行和列。MongoDB 的文档模型非常灵活,不需要预定义表结构,每个文档都可以有自己的结构和属性。这种灵活性使得 MongoDB 非常适合存储非结构化数据。
-
查询语言:MongoDB 的查询语言使用的是 JSON 格式的查询语句,可以方便地查询文档。SQL 数据库使用 SQL 查询语言,需要编写复杂的 SQL 语句进行查询。
-
索引:MongoDB 支持多种类型的索引,包括单字段索引、复合索引和全文索引等。SQL 数据库也支持索引,但相对来说功能不如 MongoDB 强大。
-
事务处理:MongoDB 支持 ACID 事务,可以确保多个操作在同一事务中原子性地执行,保证数据的一致性和完整性。SQL 数据库也支持事务处理。
-
分布式:MongoDB 支持分片集群,可以在多个服务器之间实现高可用性和可靠性,还可以进行水平扩展以适应不断增长的数据集。SQL 数据库也支持分布式,但相对来说不如 MongoDB 方便和灵活。
总之,MongoDB 和传统的 SQL 数据库有很大的区别,主要在数据模型、查询语言、索引、事务处理和分布式等方面。MongoDB 的文档型数据模型和灵活的查询语言使得它非常适合存储非结构化数据和大数据分析等场景。
快速入门
创建数据库
在MongoDB中,数据库是按需创建的,当你插入数据时,如果指定的数据库不存在,则MongoDB会自动创建一个数据库。但是如果你想手动创建一个数据库,可以使用以下命令:
use <database name>
例如,要创建名为mydb的数据库,可以使用以下命令:
use mydb
切换数据库
要切换到一个已经存在的数据库,可以使用以下命令:
use <database name>
例如,要切换到名为mydb的数据库,可以使用以下命令:
use mydb
查看当前数据库
要查看当前使用的数据库,可以使用以下命令:
db
删除数据库
要删除一个数据库,可以使用以下命令:
db.dropDatabase()
查看所有数据库
要查看MongoDB中所有的数据库,可以使用以下命令:
show dbs
创建集合
集合是MongoDB中的一种数据结构,类似于关系型数据库中的表。要创建一个集合,可以使用以下命令:
db.createCollection(<collection name>)
例如,要创建名为mycollection的集合,可以使用以下命令:
db.createCollection("mycollection")
查看集合
要查看当前数据库中的所有集合,可以使用以下命令:
show collections
插入文档
要向一个集合中插入一个文档,可以使用以下命令:
db.<collection name>.insert(<document>)
例如,要向名为mycollection的集合中插入一个文档,可以使用以下命令:
db.mycollection.insert({name: "John", age: 30})
查询文档
要从一个集合中查询文档,可以使用以下命令:
db.<collection name>.find(<query>)
例如,要从名为mycollection的集合中查询所有的文档,可以使用以下命令:
db.mycollection.find()
更新文档
要更新一个集合中的文档,可以使用以下命令:
db.<collection name>.update(<query>, <update>)
例如,要将名为mycollection的集合中所有年龄大于25岁的文档的age字段加1,可以使用以下命令:
db.mycollection.update({age: {$gt: 25}}, {$inc: {age: 1}}, {multi: true})
删除文档
要从一个集合中删除文档,可以使用以下命令:
db.<collection name>.remove(<query>)
例如,要从名为mycollection的集合中删除所有年龄小于25岁的文档,可以使用以下命令:
db.mycollection.remove({age: {$lt: 25}})
深入查询
MongoDB 的查询语法可以通过 find 方法来实现,语法如下:
db.collection.find(query, projection)
其中,query 表示查询条件,projection 表示投影条件,可以指定返回的字段。
以下是一些常用的查询语法:
全部查询
如果想查询所有文档,可以使用 find 方法,不传入任何查询条件。
示例:
// 查询 users 集合中所有文档
db.users.find()
// 查询 users 集合中所有文档
db.users.find()
条件查询
可以通过查询条件来筛选文档,常用的条件操作符包括 $eq、$ne、$gt、$gte、$lt、$lte、$in、$nin 等。
示例:
// 查询 age = 18 的文档
db.users.find({ age: 18 })
// 查询 age > 18 的文档
db.users.find({ age: { $gt: 18 } })
// 查询 age >= 18 且 name = "刘乙己" 的文档
db.users.find({ age: { $gte: 18 }, name: '刘乙己})
// 查询 age 不等于 18 的文档
db.users.find({ age: { $ne: 18 } })
// 查询 age 在 18 到 30 之间的文档
db.users.find({ age: { $gte: 18, $lte: 30 } })
// 查询 age 不在 18 到 30 之间的文档
db.users.find({ age: { $nin: [18, 30] } })
嵌套查询
如果文档中有嵌套的子文档,可以通过指定子文档字段来查询。
示例:
// 查询子文档中的字段
db.users.find({ 'address.city': 'Shenzhen' })
数组查询
如果文档中有数组字段,可以通过 $elemMatch 操作符来查询。
示例:
// 查询数组中包含特定元素的文档
db.users.find({ names: { $elemMatch: { name: '刘' }}})
// 查询包含 '刘乙己' 和 '小刘鸭' 两个用户
db.users.find({ names: { $elemMatch: { $in: ['刘乙己', '小刘鸭']}}})
投影查询
可以通过投影操作符来指定查询返回的字段。
示例:
// 只返回 name 和 age 字段
db.users.find({}, { name: 1, age: 1 })
排序查询
可以使用 sort 方法来对查询结果进行排序,排序操作符包括 1(升序)和 -1(降序)。
示例:
// 按照 age 字段升序排序
db.users.find().sort({ age: 1 })
// 按照 age 字段降序排序
db.users.find().sort({ age: -1 })
分页查询
可以使用 skip 和 limit 方法来实现分页查询,skip 方法用于指定跳过的文档数量,limit 方法用于指定返回的文档数量。
示例:
// 跳过前 10 个文档,返回 10 个文档
db.users.find().skip(10).limit(10)
聚合查询
可以使用 MongoDB 的聚合管道(Aggregation Pipeline)来进行复杂的数据聚合操作。聚合管道是一个由多个操作符组成的管道,每个操作符都会对输入文档进行一些处理,并将处理结果传递给下一个操作符。
以下是一些常用的聚合操作符:
$match:用于筛选文档,相当于查询操作符。$project:用于指定输出的文档中包含哪些字段,相当于投影操作符。$group:用于对文档进行分组聚合操作,可以指定聚合操作符。$sort:用于对聚合结果进行排序。$skip和$limit:用于实现分页查询。$unwind:用于将数组类型的字段展开成多个文档。$lookup:用于实现关联查询。$bucket:用于对数据进行分组和统计。
示例:
$group 操作符将文档分组并执行聚合函数。可以使用 $group 将文档按照指定字段进行分组,并执行一些聚合操作,如计算分组文档的数量、求和、平均数等等。
示例:
// 按照字段 category 对集合 products 进行聚合,计算每个分类下商品的平均价格和数量
db.products.aggregate([{ $group: {
_id: '$category',
averagePrice: { $avg: '$price' },
count: { $sum: 1 } } }
])
$match 操作符可以筛选集合中符合条件的文档,相当于 SQL 中的 WHERE 子句。
示例:
// 查询集合 orders 中 status 为 'completed' 的文档
db.orders.aggregate([ { $match: { status: 'completed' } } ])
$sort 操作符可以按照指定字段进行升序或降序排列,相当于 SQL 中的 ORDER BY 子句。
示例:
// 按照字段 age 对集合 users 进行排序
db.users.aggregate([ { $sort: { age: 1 } } ])
$project 操作符可以从文档中选择需要输出的字段,相当于 SQL 中的 SELECT 子句。
示例:
// 选择集合 customers 中的 name 和 age 字段,并将 _id 字段隐藏
db.customers.aggregate([ { $project: { name: 1, age: 1, _id: 0 } } ])
$limit 操作符可以限制返回的文档数量,相当于 SQL 中的 LIMIT 子句。$skip 操作符可以跳过指定数量的文档,相当于 SQL 中的 OFFSET 子句。
示例:
// 跳过前 5 条文档,并返回接下来的 10 条文档
db.customers.aggregate([ { $skip: 5 }, { $limit: 10 } ])
$unwind 操作符可以将数组类型的字段展开成多个文档,方便进行聚合操作。
示例:
// 将集合 orders 中的 items 数组展开,方便进行聚合操作
db.orders.aggregate([ { $unwind: '$items' } ])
$lookup 操作符实现关联查询。
示例:
// 将 orders 集合中的 product_id 字段与 products 集合中的 _id 字段进行关联
db.orders.aggregate([
{ $lookup: {
from: "products",
localField: "product_id",
foreignField: "_id",
as: "product"
}
}
])
$bucket 操作符对数据进行分组和统计:
示例:
// 将 sales 集合中的金额数据分为不同的桶,统计每个桶中的销售记录数量和总金额
db.sales.aggregate([
{
$bucket: {
groupBy: "$amount",
boundaries: [0, 100, 500, 1000],
default: "Other",
output: {
count: { $sum: 1 },
total: { $sum: "$amount" }
}
}
}
])
文本查询
MongoDB 支持全文本搜索,可以使用 $text 运算符来实现。
示例:
// 在集合 articles 中搜索包含 '刘乙己' 或 '小刘鸭' 的文档
db.articles.find({ $text: { $search: '刘乙己 小刘鸭' } })
正则查询
MongoDB 支持正则表达式查询,可以使用 $regex操作符进行正则表达式匹配。
示例:
db.collection.find({ name: { $regex: /^J/ } })
索引详解
MongoDB索引是一种用于提高查询性能和加速数据检索的数据结构,可以理解为数据库的目录。通过索引,MongoDB可以在执行查询时快速定位到匹配条件的数据,从而避免全表扫描的开销,提高查询效率。
MongoDB支持多种类型的索引,包括:
-
单键索引:对单个字段建立的索引。
-
复合索引:对多个字段建立的索引。
-
全文索引:对文本数据建立的索引,用于支持全文搜索。
-
地理位置索引:对地理位置数据建立的索引,用于支持地理位置搜索。
-
哈希索引:对哈希值建立的索引,用于支持散列查找。
-
TTL(Time-To-Live)索引:用于自动过期数据的索引。
-
部分索引:只对满足特定条件的文档建立索引。
-
背景索引:对索引的建立和重建操作在后台进行,不会阻塞其他操作。
索引可以大大提高查询效率,但也需要付出一定的代价,比如增加写入时的成本和占用存储空间。因此,在建立索引时需要根据具体情况进行权衡和优化。
单键索引
单键索引是最简单、也是最常用的一种索引类型,它只针对一个字段创建索引。在MongoDB中,可以使用createIndex方法创建单字段索引,如下所示:
db.collection.createIndex({ field: 1 })
其中,collection是集合名称,field是需要创建索引的字段名,1表示升序排序,-1表示降序排序。需要注意的是,索引创建后需要一定时间才能生效,具体时间取决于数据量和硬件性能。
复合索引
复合索引是一种包含多个字段的索引类型,它可以提高多条件查询的性能。在MongoDB中,可以使用createIndex方法创建复合索引,如下所示:
db.collection.createIndex({ field1: 1, field2: -1 })
其中,field1和field2是需要创建索引的字段名,1和-1表示升序排序和降序排序。需要注意的是,复合索引中字段的顺序非常重要,查询时必须按照索引顺序指定查询条件,否则索引将失效。
全文索引
全文索引是一种用于支持全文搜索的索引类型,可以对文本数据进行高效的模糊匹配。在MongoDB中,可以使用createIndex方法创建全文索引,如下所示:
db.collection.createIndex({ field: "text" })
其中,field是需要创建索引的字段名,"text"表示该字段为全文索引。需要注意的是,全文索引只支持少数的数据类型,包括字符串、数组和嵌套文档。
地理空间索引
地理空间索引是一种用于支持地理空间查询的索引类型,可以对地理位置数据进行高效的查询和计算。在MongoDB中,可以使用createIndex方法创建地理空间索引,如下所示:
db.collection.createIndex({ location: "2dsphere" })
其中,location是需要创建索引的地理位置字段名,"2dsphere"表示该字段为地理空间索引。需要注意的是,地理空间索引只能用于存储GeoJSON格式的地理位置数据。
哈希索引
对哈希值建立的索引,用于支持散列查找。哈希索引会对指定字段的值进行哈希处理,然后将哈希值存储在B树(B-tree)索引中。如下所示:
db.collection.createIndex({field: "hashed"})
TTL(Time-To-Live)索引
用于自动过期数据的索引。TTL索引可以在指定的时间之后自动删除文档,从而实现自动清理过期数据的功能。如下所示:
db.collection.createIndex({timestamp: 1}, {expireAfterSeconds: 3600})
这会在timestamp字段上创建一个TTL索引,其中expireAfterSeconds选项指定文档的过期时间为3600秒。
部分索引
部分索引是一种只针对集合中符合特定条件的文档进行索引的方式。这样可以减少索引的大小,并提高查询性能。如下所示:
db.collection.createIndex( { name: 1 },
{ partialFilterExpression: { age: { $gte: 18 } }
})
在创建部分索引时,可以指定一个筛选器,只有符合筛选器条件的文档才会被索引。这个筛选器可以是任意的 MongoDB 查询表达式。
背景索引
背景索引是一种 MongoDB 索引的创建方式,它会在后台进行索引的建立或重建操作,而不会阻塞其他操作。这意味着在创建或重建索引的同时,应用程序仍然可以执行其他操作,不必等待索引操作完成。
创建背景索引的方式很简单,在创建索引时,只需指定 { background: true } 参数即可,如下所示:
db.collection.createIndex( { name: 1 }, { background: true } )
需要注意的是,虽然背景索引不会阻塞其他操作,但是它会占用系统资源,因此应该在适当的时间创建或重建索引,以免影响系统的正常运行。此外,背景索引的创建或重建可能会消耗较长的时间,需要耐心等待。
事务
MongoDB 支持 ACID 事务,包括多文档事务和单文档事务两种类型。在 MongoDB 4.0 版本之前,MongoDB 只支持单文档事务,而在 MongoDB 4.0 版本之后,MongoDB 支持了多文档事务。
单文档事务
单文档事务是 MongoDB 3.6 版本中引入的事务类型,可以在单个文档上执行事务操作。单文档事务使用 $isolated 操作符,将事务操作隔离在一个独立的事务中执行。
以下是单文档事务的基本语法:
db.collection.update(
{ _id: doc_id },
{ $set: { field: value } },
{ multi: false, upsert: false, isolated: true, writeConcern: { w: "majority" } }
)
多文档事务
多文档事务是 MongoDB 4.0 版本中引入的事务类型,可以在多个文档上执行事务操作。多文档事务使用 session 对象来管理事务。
以下是多文档事务的基本语法:
session = client.startSession();
session.startTransaction();
try {
// 在事务中执行操作
session.commitTransaction();
} catch (error) {
session.abortTransaction();
}
在多文档事务中,可以在一个事务中执行多个操作,包括插入、更新、删除等操作。如果事务操作执行成功,可以通过 session.commitTransaction() 方法提交事务,否则可以通过 session.abortTransaction() 方法回滚事务。
需要注意的是,MongoDB 的事务操作在分片集群中有一些限制,因此在使用事务时需要注意其适用范围和使用方法。
MongoDB 的事务机制
MongoDB 的事务机制包括单文档事务和多文档事务。单文档事务是 MongoDB 3.6 版本中引入的事务类型,可以在单个文档上执行事务操作。多文档事务是 MongoDB 4.0 版本中引入的事务类型,可以在多个文档上执行事务操作。在 MongoDB 中,事务可以保证数据的一致性和隔离性,并且受到 write concern 的限制,只有当 write concern 设置为 majority 时,事务才会成功提交。
MVCC
MVCC(多版本并发控制)是一种常见的数据库并发控制技术,它可以提高数据库的并发性能和吞吐量,避免数据的冲突和丢失。MVCC 在 MongoDB 中得到广泛应用,是 MongoDB 中事务机制的基础。
在传统的并发控制技术中,数据库使用锁来保证并发操作的正确性,但是锁在高并发环境下会成为性能瓶颈,而且容易导致死锁和竞争条件等问题。MVCC 的思想是,在每次数据修改时生成一个新版本的数据,并将旧版本的数据保留下来。每个版本的数据都包含一个版本号,该版本号与事务的时间戳进行比较,以确定事务的可见性。这样,不同版本的数据可以并发访问,而不会互相干扰。
在 MongoDB 中,每个文档都会维护一个 _id 字段作为唯一标识符,并且每个文档还会维护一个 _id 和一个 value 字段,其中 _id 表示文档的版本号,value 表示文档的实际数据。当进行数据修改时,MongoDB 会生成一个新的 _id 和一个新的 value,然后将新的 _id 和 value 写入数据库中,并将旧的 _id 和 value 标记为删除状态。这样,旧的版本可以继续被查询,而不会影响新版本的数据。
在 MVCC 中,每个事务在执行时都会获取一个 snapshot(快照),该快照包含当前所有活跃的文档版本。在事务执行期间,事务只能看到在该 snapshot 中存在的文档版本,而无法看到在该 snapshot 之后创建或修改的文档版本。在事务提交之前,MongoDB 会检查所有修改的文档是否存在冲突,如果存在冲突,则事务会失败,所有修改的数据都会回滚。如果所有修改都成功,则事务会被提交,所有修改都会应用到数据库中。
MVCC 的优点在于,它可以避免数据的冲突和丢失,提高数据库的并发性能和吞吐量,而且实现相对简单。但是,MVCC 也存在一些缺点。首先,MVCC 需要额外的存储空间用于维护版本信息,这会增加数据库的存储成本。其次,在高并发环境下,MVCC 可能会导致性能问题,因为每个事务都需要获取一个 snapshot,如果事务过多,会导致快照的数量过多,从而影响数据库的性能。此外,MVCC 还可能导致数据一致性的问题,例如,在一个写密集的系统中,如果存在大量的读取操作,那么会导致数据版本的快速增长,从而增加数据库存储的成本。另外,如果存在长时间运行的事务,那么快照的数量也会增加,从而占用更多的内存,影响数据库的性能。此外,MVCC 还可能导致读取到过期数据的问题,因为快照只包含在该快照创建之前已经存在的文档版本,如果在快照创建后有新的文档版本被创建,那么事务就无法看到这些新的文档版本,从而导致读取到过期数据。
为了避免 MVCC 的缺点,MongoDB 提供了多种优化技术,例如索引、缓存和压缩等。其中,索引可以加速查询操作,缓存可以减少磁盘 I/O 操作,压缩可以减少存储空间的使用。此外,MongoDB 还支持读写分离和分片技术,可以将负载分散到多个节点上,从而提高数据库的并发性能和可扩展性。
总的来说,MVCC 是一种高效、可靠的数据库并发控制技术,在 MongoDB 中得到了广泛的应用。通过维护多个版本的文档数据,并使用快照机制控制事务的可见性,MVCC 可以提高数据库的并发性能和吞吐量,避免数据的冲突和丢失。但是,MVCC 也存在一些缺点,例如存储成本、性能问题和数据一致性等,需要通过优化技术来解决。
write concern
write concern 是 MongoDB 中用于控制数据写入行为的一个参数。它决定了 MongoDB 在写入数据时的行为,例如写入数据到多少个副本才算成功,以及在写入数据时是否需要等待副本集中的大多数节点都确认接收数据。在 MongoDB 中,write concern 还用于控制事务提交时的行为,只有当 write concern 设置为 majority 时,事务才会成功提交。
Write Concern 的概念
在 MongoDB 中,每个写入操作都必须有一个 Write Concern 参数,指定了数据写入的可靠性和一致性级别。Write Concern 有三个参数:
- w:表示写入操作需要写入的副本数。默认值为 1,表示写入主节点上的一个副本即可。可以设置为大于 1 的整数,表示写入主节点和指定数量的副本节点。
- j:表示写入操作需要写入到磁盘上的持久存储中。默认值为 false,表示写入操作不需要写入到磁盘上的持久存储中。可以设置为 true,表示写入操作需要写入到磁盘上的持久存储中。
- wtimeout:表示写入操作需要等待的时间,以毫秒为单位。默认值为 0,表示写入操作不需要等待。可以设置为大于 0 的整数,表示写入操作需要等待指定的时间,如果超时则抛出异常。
Write Concern 的值可以在多个级别进行设置,包括:
- 全局级别:使用 MongoDB 驱动程序的默认 Write Concern 设置,适用于所有写入操作。
- 数据库级别:对整个数据库进行设置,适用于该数据库中的所有集合。
- 集合级别:对集合进行设置,适用于该集合中的所有写入操作。
- 操作级别:针对每个写入操作进行设置。
Write Concern 的级别越高,数据写入的可靠性和一致性级别就越高,但也会增加数据写入操作的延迟和系统开销。
Write Concern 的实现
MongoDB 通过多种机制来实现 Write Concern 的功能。具体来说,MongoDB 实现了以下几个方面的功能:
-
副本集:MongoDB 可以在多个节点之间进行数据复制和数据同步,以提高数据库的可靠性和可用性。在副本集中,一个节点被指定为主节点,负责接收写入请求和处理查询请求。其他节点被指定为副本节点,负责接收从主节点复制的数据,并在主节点失效时自动接管主节点的职责。副本集可以通过 Write Concern 的 w 参数来指定写入操作需要写入的副本数,以确保数据写入的可靠性和一致性。
-
日志:MongoDB 可以将所有的写入操作记录在一个操作日志中,以确保数据写入操作可以被持久化。操作日志可以通过 Write Concern 的 j 参数来指定写入操作需要写入到磁盘上的持久存储中,以确保写入操作不会在数据库出现故障时丢失。
-
单调读:MongoDB 保证单调读的语义,即如果一个客户端看到了一个文档的更新,那么它也一定能看到这个文档的所有更新。这是通过在主节点上对写入操作进行加锁,以保证在写入操作完成之前,其他客户端不能读取到文档的更新。
-
时间戳:MongoDB 为每个写入操作分配一个唯一的时间戳,以便在多个节点之间进行数据同步和数据复制时进行顺序控制。时间戳可以用来保证数据写入操作的一致性,即保证较新的写入操作不会被较旧的写入操作覆盖。
Write Concern 的最佳实践
在使用 MongoDB 的 Write Concern 功能时,应该考虑以下几个方面:
应该根据应用程序的需求选择合适的 Write Concern 值。如果应用程序需要较高的数据可靠性和一致性,可以选择较高的 w 和 j 参数值。如果应用程序需要较低的延迟和开销,可以选择较低的 w 和 j 参数值。
应该将 Write Concern 的值尽可能地设置为局部级别,以便更精确地控制数据写入操作的可靠性和一致性级别。
应该避免在高并发的情况下使用较高的 Write Concern 值,因为这会增加数据库的延迟和开销,并可能导致数据库性能下降。
应该根据实际情况定期检查 Write Concern 的设置,并根据应用程序的需求进行调整。如果应用程序的需求发生了变化,需要重新评估 Write Concern 的值。
总结
Write Concern 是 MongoDB 中一个非常重要的功能,用于控制数据写入操作的可靠性和一致性级别。在使用 Write Concern 功能时,应该根据应用程序的需求选择合适的参数值,并将其设置为局部级别,以便更精确地控制数据写入操作的可靠性和一致性级别。此外,应该避免在高并发的情况下使用较高的 Write Concern 值,以避免影响数据库的性能和可用性。
存储结构
MongoDB的存储结构可以分为逻辑结构和物理结构两个方面。
逻辑结构
MongoDB的逻辑结构包含数据库、集合和文档三个层次。
-
数据库:MongoDB的数据存储在数据库中,数据库是一个逻辑容器,可以存储多个集合。每个数据库都有一个唯一的名称,您可以使用该名称来访问该数据库。
-
集合:集合是MongoDB中的一个逻辑概念,它类似于关系型数据库中的表。集合包含多个文档,每个文档都可以具有不同的结构和字段。MongoDB不需要提前定义集合的结构,这使得它更加灵活和适应变化。
-
文档:文档是MongoDB中的基本单位,它是一个键值对的集合,类似于JSON对象。文档可以包含任意数量和类型的字段,这使得MongoDB非常灵活。
物理结构
MongoDB的物理存储结构包括数据文件、日志文件、索引文件等。
-
数据文件:MongoDB使用数据文件来存储数据。每个数据文件都有一个固定的大小,通常为64MB或128MB。当一个数据文件达到其最大大小时,MongoDB会创建一个新的数据文件。
-
日志文件:MongoDB使用日志文件来记录写入操作,以便在系统故障或崩溃时进行恢复。MongoDB使用两种类型的日志文件:操作日志(oplog)和诊断日志(diaglog)。
-
索引文件:MongoDB使用B树索引来加速数据查询和排序。每个索引都存储在一个磁盘文件中,文件名与索引名称相同。MongoDB支持多种类型的索引,包括单字段索引、多字段索引、文本索引和地理空间索引等。
-
配置文件:MongoDB使用配置文件来存储服务器的配置参数,例如网络设置、安全设置和日志设置等。
-
锁文件:MongoDB使用锁文件来确保只有一个MongoDB进程可以访问数据库。锁文件通常存储在MongoDB数据目录下的mongod.lock文件中。
MongoDB的存储结构包括逻辑结构和物理结构两个方面。逻辑结构包括数据库、集合和文档三个层次,物理结构包括数据文件、日志文件、索引文件等。MongoDB的存储结构非常灵活,使得它可以适应各种不同的应用场景。

浙公网安备 33010602011771号