从本地存储到数据库:了解 MongoDB 结构❗
引言
1. 我们的起点:SQL 世界
2. NoSQL 的故事:不仅仅是 SQL
3. 从本地存储到数据库
4. 基本 CRUD 操作:
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
引言
大家好!🤗 如果你是一名刚开始接触数据库的开发者,或者你已经掌握了基础知识,想要复习一下或者更深入地了解,我希望这篇文章能对你有所帮助。
我学习新事物时,喜欢深入钻研,理解其背后的逻辑,确保完全理解。因此,我这篇文章的结构是从NoSQL基础知识讲起,一直到内部数据存储机制,重点在于解释数据库背后的原理。祝你阅读愉快!🥰
本文将探讨以下内容:
1. 我们的起点:SQL 世界
当我们使用关系型数据库(例如MySQLSQL 或 SQL Server )时PostgreSQL,数据会整齐地排列在结构完美的表格中。我们必须确保每一行都遵循从一开始就设定好的严格列结构。如果需要更改这种结构,我们基本上就得停下来,处理复杂的变更,然后祈祷所有现有数据仍然能够兼容。
诚然,这种方式带来了一致性和逻辑性,但随着应用程序规模的不断扩大,这种僵化的结构成为了快速迭代的真正瓶颈。
2. NoSQL 的故事:不仅仅是 SQL
说到NoSQL数据库,你可能听说过NoSQL,但让我们澄清一下:它并非完全反对 SQL SQL!正确且现代的解释是:不仅仅是 SQL!
为什么“不只是 SQL”❓
因为我们意识到,某些任务(其中严格的关联性和一致性至关重要SQL)需要极高的性能,而如今的现代应用(社交网络、游戏、网站)则需要速度和灵活性。因此,它是一种补充,一种替代方案,使我们能够为合适的工作选择合适的工具。我们并没有放弃,只是为我们的工具包增添了更强大的工具。NoSQLSQL
3. 从本地存储到数据库
在众多类型的NoSQL数据库中,MongoDB 属于文档型数据库。
想象一下,数据不再存储在单独的行和列中。相反,您可以将完整的记录(例如,包含所有地址、订单和偏好的用户个人资料)存储在一个名为“文档”的单个包中。
文档:
→ 文档是基本构建块。它看起来和JSONJavaScript 对象 (BSON) 完全一样,但严格来说,MongoDB 使用的是BSON二进制格式 (BSON JSON)。为什么是 BSON 呢?因为它是一种速度更快的二进制格式,并且包含了JavaScript 对象所不具备的数据类型(例如日期/时间值)。JSON
→ 所有这些文档(请注意,它们不必完全相同)都被分组到一个集合中,集合是一种取代旧表的文件夹。为了便于理解,我们可以将文档视为存储在表中的值localStorage,但它们的功能远比表中的简单字符串值强大得多localStorage❗
→ 文档是MongoDB 中最小也是最重要的数据单元,它包含了完整的信息,并提供了极大的灵活性,允许:
→ 存储嵌套对象,
→ 存储列表,
→ 直接存储复杂数据类型(例如日期/时间)。
这里我们有一个Document:
{ // unique ID
"_id": ObjectId("61a5c6f0e8f0b7c4d5a9b8c7"),
// complex data type: Date/Time
"order_date": ISODate("2025-11-18T10:00:00Z"),
"status": "Shipped",
// nested object
"shipping_address": {
"street": "10 Example Blvd",
"city": "London",
"zip_code": "SW1A 0AA"
},
// list (Array)
"items": [
{
"product_name": "Laptop Pro",
"quantity": 1,
"price": 1200.00
},
{
"product_name": "Mouse Wireless",
"quantity": 2,
"price": 25.50
}
]
}
收藏:
→ 如果文档相当于单个记录(例如存储在表中的复杂值localStorage或行SQL),那么 MongoDB 中的集合就是将所有这些记录保存在一起的文件夹。
→ MongoDB 中的数据结构在Collection概念上等同于关系型数据库中的表。与关系型数据库中所有行必须遵循相同结构(相同列)不同,MongoDB 中的数据结构可以不同(动态模式)❗SQLSQLDocumentsCollection
→ 举个简单的例子,在 MongoDB 中,我们有一个名为 `students` 的数据库school。这个数据库包含两个变量Collections:学生和教师
。
→ 1. 该students系列包含两份文件:
{
first_name: "Alice",
last_name: "Smith",
age: 16,
grade: 10,
enrollment_date: new Date("2024-09-01T00:00:00Z"),
courses: ["Math", "Physics", "English"] // Array
},
{
first_name: "Bob",
last_name: "Johnson",
age: 17,
grade: 11,
enrollment_date: new Date("2023-09-01T00:00:00Z"),
contact: { // nested object
phone: "555-1234",
email: "bob@school.edu"
}
}
- 教师资料
Collection包含两份文件:
{
title: "Mr.",
last_name: "Davis",
subject: "Mathematics",
tenure: true,
phone: "555-5678"
class_count: 5
},
{
title: "Ms.",
last_name: "Garcia",
subject: "History",
class_count: 4,
office_hours: { // Nested Object
day: "Wednesday",
time: "2:00 PM - 3:00 PM"
}
}
天生的灵活性:
→ 一个用户文档可能包含某个phone字段,而下一个用户文档可能不包含。这种动态模式是开发人员在处理快速变化的数据时选择 MongoDB 的主要原因。
→ 因此,MongoDB 允许我们自然地对数据进行建模,例如对象(文档),并且这些对象在称为逻辑组的逻辑组中得到高效管理Collections。
基本字段:_id
→ 每个文档都必须有一个名为_id. 的唯一字段。该字段用作文档的主键(就像 SQL 行中的唯一 ID 一样)。
→ 如果您在插入数据时没有指定 _id,MongoDB 会自动使用一种名为ObjectId的特殊数据类型为您生成一个。此 ObjectId 保证唯一,甚至包含时间戳,让您可以获取文档创建的确切时间。
4. 基本 CRUD 操作:
(假设 MongoDB 服务器已安装且 mongosh 已准备就绪,我们现在可以连接到数据库,看看如何创建集合和文档)……
→CRUD操作代表了任何持久数据存储系统所依赖的四个基本功能。在数据库(例如 MongoDB,尽管这些术语普遍适用)的上下文中,这些是我们与数据库进行交互的方法。DocumentsCollection
1. 创建:insertOne()/insertMany()
→ 该Create操作会将新文档添加到集合中。
insertOne(document):此方法用于向集合中插入单个新文档。
//this will add a new document in
//teachers collection
db.teachers.insertOne({
title: "Mr.",
last_name: "Jack",
subject: "Geography",
tenure: false,
phone: "555-5566"
class_count: 6
})
insertMany([document1, document2, ...])此方法用于通过单个命令将多个文档插入集合中。参数是一个文档数组(列表)。
//this will add two documents in
//students collection
db.students.insertMany([
{
first_name: "Lea",
last_name: "Casy",
age: 17,
grade: 10
},
{
first_name: "Jessy",
last_name: "Smith",
age: 18,
grade: 10
}
])
2. 阅读:find()/findOne()
→ 该Read操作根据筛选条件从集合中检索文档。
findOne(query)此方法返回符合查询对象中指定筛选条件的第一个文档。如果您知道只需要单个文档(例如,基于唯一 ID),则此方法非常理想。如果未指定查询(即查询对象为空:{}),则返回集合中找到的第一个文档。
//find the first student with name 'Lea'
db.students.findOne({ first_name: 'Lea' })
find(query)此方法返回一个指向所有符合指定筛选条件的文档的游标。如果查询对象为空({}),则返回集合中的所有文档。
//return all of documents from students colection
db.students.find()
//find all students whose age is greater than 16
db.students.find({ age: {$gt: 16 }})
3. 更新:updateOne()/updateMany()
updateOne(filter, update_operation)更新符合给定筛选条件的第一个文档。
//finds the document with `first_name 'Jessy'` and
// sets the new grade to false.
db.students.updateOne(
{ first_name: 'Jessy' },
{ $set: { grade: false } }
)
updateMany(filter, update_operation)更新所有符合给定筛选条件的文档。
// It selects documents only if the field contact is absent. ($exists: false)
// and add the 'contact' object with default phone and email values.
db.students.updateMany(
// 1. FILTER: Select documents missing the 'contact' field
{ contact: { $exists: false } },
// 2. OPERATION: Use $set to add the new 'contact' object
{
$set: {
"contact.phone": false,
"contact.email": "default@school.com"
}
}
);
→ 基本$set运算符:这是最常用的更新运算符。它指定要修改哪些字段以及它们的新值。它可以替换现有字段的值,或者在字段不存在时添加新字段。
基本语法:在更新调用中,更新操作部分通常如下所示:{"$set": {"field_name": "new_value", "another_field": 123}}。
4.删除:deleteOne()/deleteMany
→ 删除操作会从集合中移除文档。deleteOne(filter):删除与指定筛选条件匹配的第一个文档。
// delete the first student found whose first name is 'Lea'.
db.students.deleteOne({ first_name: "Lea" })
deleteMany(filter):删除所有符合指定筛选条件的文档。
// delete all students who are currently in grade 10.
db.students.deleteMany({ grade: 10 });
注意❗如果您使用deleteMany({})空筛选器,将会删除集合中的所有文档。使用删除操作时务必谨慎。🙃
删除集合:db.students.drop(),
删除数据库:首先选择数据库use school,然后删除它。db.dropDatabase()
结论❤️
虽然我还没有深入研究具体使用的工具,但我撰写第一篇文章的目标是对 MongoDB 的基础知识做一个简短而扎实的介绍。
MongoDB 的世界博大精深,值得探索的内容很多,但我认为这些基础知识至关重要。如果你理解了 localStorage 中的数据保存和检索机制,就可以将其类比,更好地理解数据库中的集合。🙃
我很快会发布更详细的文章,进一步深入探讨我们已经学过的概念。希望这篇入门指南对你有所帮助!
如果你喜欢这篇文章,学到了新知识,或者想起了自己第一次接触MongoDB 的经历,别忘了点赞或留言!非常感谢你的阅读,也感谢你抽出宝贵时间阅读这篇文章。期待下次与你交流!祝你编程愉快!🥰🤗
文章来源:https://dev.to/cristea_theodora_6200140b/from-localstorage-to-database-understanding-the-mongodb-struct-1a21