大家在用mongodb进行数据库设计的时候是怎么个思路?【Nodejs版】
大家在用mongodb进行数据库设计的时候是怎么个思路?【Nodejs版】
关系型数据库设计的时候感觉很简单,思路很清晰。转到mongodb后感觉不是很清楚,不知道什么时候将一个集合(table)嵌套进另一个集合,不知道应该在什么时候将集合独立出来,通过引用来表示集合间的关系。这个应该怎么做?
在使用MongoDB进行数据库设计时,相比于关系型数据库,MongoDB采用了一种更灵活的文档模型。这种模型允许我们根据实际需求来决定何时嵌套数据(即嵌入式模式)或何时通过引用来表示集合间的关系(即引用模式)。以下是一些基本的指导原则和示例代码,帮助你理解这两种模式。
嵌入式模式
当你需要频繁访问两个集合的数据,并且这些数据通常一起被读取时,可以考虑使用嵌入式模式。例如,如果一个用户有很多地址信息,而这些地址信息总是与用户信息一起被查询,那么你可以选择将地址信息嵌入到用户的文档中。
示例代码:
const mongoose = require('mongoose');
const addressSchema = new mongoose.Schema({
street: String,
city: String,
state: String,
zip: String
});
const userSchema = new mongoose.Schema({
name: String,
email: String,
addresses: [addressSchema] // 嵌入式数组
});
const User = mongoose.model('User', userSchema);
// 创建用户并添加地址
const newUser = new User({
name: 'John Doe',
email: 'john@example.com',
addresses: [
{
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345'
}
]
});
newUser.save()
.then(() => console.log('User saved'))
.catch(err => console.error(err));
引用模式
当数据之间存在松散耦合关系,或者需要跨多个集合进行查询时,可以考虑使用引用模式。例如,如果你有多个用户分享同一个地址,那么最好将地址存储在一个单独的集合中,并通过引用来链接它们。
示例代码:
const addressSchema = new mongoose.Schema({
street: String,
city: String,
state: String,
zip: String
});
const userSchema = new mongoose.Schema({
name: String,
email: String,
addressId: { type: mongoose.Schema.Types.ObjectId, ref: 'Address' } // 引用
});
const Address = mongoose.model('Address', addressSchema);
const User = mongoose.model('User', userSchema);
// 创建地址
const newAddress = new Address({
street: '123 Main St',
city: 'Anytown',
state: 'CA',
zip: '12345'
});
// 创建用户并设置地址引用
const newUser = new User({
name: 'Jane Doe',
email: 'jane@example.com',
addressId: newAddress._id
});
// 保存地址和用户
Promise.all([newAddress.save(), newUser.save()])
.then(() => console.log('Address and User saved'))
.catch(err => console.error(err));
通过上述示例,你可以看到如何根据实际情况选择合适的数据库设计策略。希望这能帮助你更好地理解和应用MongoDB的设计理念。
从查询的角度来设计
同问,迷茫了。。。
也有这个疑惑。。
你的意思是只要方便查询就行是吗,其他的可以不考虑?
在使用 MongoDB 进行数据库设计时,主要关注点是文档模型以及如何有效地组织数据。与关系型数据库不同,MongoDB 是一种 NoSQL 数据库,其数据模型基于文档(通常是 JSON 文档)。在设计时需要考虑以下几点:
- 数据访问模式:了解应用程序的数据访问模式,比如经常一起查询的数据是否应该嵌入同一个文档中。
- 数据一致性:MongoDB 提供了事务支持,但通常更注重性能而不是强一致性。如果需要保持强一致性,可能需要自己实现逻辑。
- 嵌入 vs 引用:
- 嵌入:当两个文档之间的关系紧密且数据大小适中时,可以考虑将一个文档嵌入到另一个文档中。这有助于减少查询次数,提高读取效率。
- 引用:当两个文档之间存在松散关系或数据量较大时,可以使用引用的方式,通过引用 ID 来关联数据。
示例
假设我们有一个博客应用,需要设计用户(User)和文章(Post)的模型。
嵌入式设计
const mongoose = require('mongoose');
const postSchema = new mongoose.Schema({
title: String,
content: String,
author: {
name: String,
email: String
}
});
const Post = mongoose.model('Post', postSchema);
// 创建一个新文章
const newPost = new Post({
title: 'Hello World',
content: 'This is my first blog post.',
author: {
name: 'John Doe',
email: 'john.doe@example.com'
}
});
newPost.save();
引用式设计
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String
});
const User = mongoose.model('User', userSchema);
const postSchema = new mongoose.Schema({
title: String,
content: String,
authorId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User' // 引用 User 模型
}
});
const Post = mongoose.model('Post', postSchema);
// 创建一个新用户
const newUser = new User({
name: 'John Doe',
email: 'john.doe@example.com'
});
newUser.save();
// 创建一个新文章
const newPost = new Post({
title: 'Hello World',
content: 'This is my first blog post.',
authorId: newUser._id // 使用用户ID引用用户
});
newPost.save();
总结
在选择嵌入还是引用时,需要根据实际需求来决定。如果频繁访问的数据被嵌入在一起,那么性能会更好。如果数据规模较大或者关系较松散,使用引用更为合适。