大家在用mongodb进行数据库设计的时候是怎么个思路?【Nodejs版】

大家在用mongodb进行数据库设计的时候是怎么个思路?【Nodejs版】

关系型数据库设计的时候感觉很简单,思路很清晰。转到mongodb后感觉不是很清楚,不知道什么时候将一个集合(table)嵌套进另一个集合,不知道应该在什么时候将集合独立出来,通过引用来表示集合间的关系。这个应该怎么做?

6 回复

在使用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 文档)。在设计时需要考虑以下几点:

  1. 数据访问模式:了解应用程序的数据访问模式,比如经常一起查询的数据是否应该嵌入同一个文档中。
  2. 数据一致性:MongoDB 提供了事务支持,但通常更注重性能而不是强一致性。如果需要保持强一致性,可能需要自己实现逻辑。
  3. 嵌入 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();

总结

在选择嵌入还是引用时,需要根据实际需求来决定。如果频繁访问的数据被嵌入在一起,那么性能会更好。如果数据规模较大或者关系较松散,使用引用更为合适。

回到顶部