Nodejs中mongodb的用法能否代替关系数据库中的子表?

Nodejs中mongodb的用法能否代替关系数据库中的子表?

想在mongo中用子集合代替关系数据库中的子表,试用了几次,添加和更新都有各种不方便,有希望替代不,如何处理?

5 回复

Node.js 中 MongoDB 的用法能否代替关系数据库中的子表?

在关系型数据库(如 MySQL 或 PostgreSQL)中,我们通常使用外键和子表来表示实体之间的关联。而在 NoSQL 数据库如 MongoDB 中,我们可以使用嵌套文档或引用来实现类似的功能。那么,MongoDB 是否可以完全替代关系数据库中的子表呢?

嵌套文档 vs 引用

  1. 嵌套文档:这种方式类似于关系数据库中的子表,将相关的数据存储在一个文档内部。
  2. 引用:这种方式类似于外键,通过引用另一个文档的 ID 来建立关联。

示例代码

假设我们有一个 UserPost 的关系,每个用户可以有多篇帖子。

使用嵌套文档
const mongoose = require('mongoose');

const postSchema = new mongoose.Schema({
    title: String,
    content: String,
});

const userSchema = new mongoose.Schema({
    name: String,
    posts: [postSchema]
});

const User = mongoose.model('User', userSchema);

// 添加一个用户及其帖子
async function addUserWithPosts() {
    const newUser = new User({
        name: 'John Doe',
        posts: [
            { title: 'First Post', content: 'This is the first post.' },
            { title: 'Second Post', content: 'This is the second post.' }
        ]
    });

    await newUser.save();
}

// 获取用户的全部帖子
async function getUserPosts() {
    const user = await User.findOne({ name: 'John Doe' }).populate('posts');
    console.log(user.posts);
}
使用引用
const mongoose = require('mongoose');

const postSchema = new mongoose.Schema({
    title: String,
    content: String,
});

const userSchema = new mongoose.Schema({
    name: String,
    posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }]
});

const Post = mongoose.model('Post', postSchema);
const User = mongoose.model('User', userSchema);

// 添加一个用户及其帖子
async function addUserWithPosts() {
    const newUser = new User({
        name: 'John Doe'
    });

    const newPost1 = new Post({
        title: 'First Post',
        content: 'This is the first post.'
    });
    const newPost2 = new Post({
        title: 'Second Post',
        content: 'This is the second post.'
    });

    await newPost1.save();
    await newPost2.save();

    newUser.posts.push(newPost1._id);
    newUser.posts.push(newPost2._id);

    await newUser.save();
}

// 获取用户的全部帖子
async function getUserPosts() {
    const user = await User.findOne({ name: 'John Doe' }).populate('posts');
    console.log(user.posts);
}

总结

  • 嵌套文档:适用于数据量较小且关系较为固定的情况,易于管理和查询。
  • 引用:适用于数据量较大且需要灵活管理的情况,但查询时需要进行额外的关联操作。

因此,在某些场景下,MongoDB 可以有效地替代关系数据库中的子表,但在其他复杂场景中可能需要更多的考虑和设计。


mongoose其实很好用很方便。首先,这是一个习惯问题,其次这是一个习惯问题。。。

mongodb不太适合多表关联操作,如果你真需要,就要重新设计表结构。dbref不能做到级联更新。

MongoDB 是一种文档数据库,可以使用嵌入式文档(嵌套文档)来模拟关系数据库中的子表。这种方法通常被称为“嵌入式模式”或“引用模式”。然而,在实际应用中,是否能完全替代关系数据库中的子表取决于具体的应用场景。

嵌入式模式

嵌入式模式是指将一个实体的所有数据都存储在一个文档中。例如,假设我们有一个 OrderProduct 的关系,可以用嵌入式模式将 Product 文档嵌入到 Order 文档中:

const mongoose = require('mongoose');

const productSchema = new mongoose.Schema({
    name: String,
    price: Number
});

const orderSchema = new mongoose.Schema({
    customerName: String,
    products: [productSchema] // 子文档数组
});

const Order = mongoose.model('Order', orderSchema);

// 创建订单并添加产品
const newOrder = new Order({
    customerName: 'John Doe',
    products: [
        { name: 'Product A', price: 100 },
        { name: 'Product B', price: 200 }
    ]
});

newOrder.save()
    .then(savedOrder => console.log(savedOrder))
    .catch(err => console.error(err));

引用模式

引用模式是指在一个文档中只存储另一个文档的引用(通常是 _id)。这样可以实现松耦合的设计,并且有助于性能优化:

const productSchema = new mongoose.Schema({
    name: String,
    price: Number
});

const orderSchema = new mongoose.Schema({
    customerName: String,
    productIds: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Product' }]
});

const Product = mongoose.model('Product', productSchema);
const Order = mongoose.model('Order', orderSchema);

// 创建产品
const newProduct = new Product({ name: 'Product A', price: 100 });
newProduct.save();

// 创建订单并引用产品
const newOrder = new Order({
    customerName: 'John Doe',
    productIds: [newProduct._id]
});
newOrder.save()
    .then(savedOrder => console.log(savedOrder))
    .catch(err => console.error(err));

总结

嵌入式模式适合于数据量较小且紧密关联的情况,而引用模式则适用于数据量较大或需要频繁查询和更新的情况。根据你的具体需求选择合适的方法,以达到最佳的性能和可维护性。

回到顶部