求教关于Nodejs mongo数据同步的问题,求大神
求教关于Nodejs mongo数据同步的问题,求大神
现在有两张表,A和B,A是记录用户信息的表,B是记录用户发布的文章内容的表。
我现在在B中有个字段是用来记录A中的用户名的,这样可以让我我知道B中的文章都是哪些用户发布的,但是现在遇到的问题是如果A表中的用户字段被用户自己修改了,但是B表中用户名这个字段如何才能跟着A表的修改一起同步了。
现在有一种解决方法是我在B表记录A的表用户的ID,然后每次读取B表的数据的时候去查询A表的用户信息,但是这样性能太低了,因为假设我现在在做一个文章列表需要展示用户名这个字段,那我没展示一条文章就需要去查询一次A表。
对于这个问题,我们可以使用MongoDB的引用或者嵌入的方式来解决。下面是两种可能的解决方案:
解决方案一:使用MongoDB的引用
在这种情况下,我们在B表中存储A表的用户ID而不是用户名。这样,当A表中的用户名发生变化时,我们只需要更新一个地方即可。
示例代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 用户模型
const UserSchema = new Schema({
username: { type: String, required: true },
// 其他用户字段...
});
const User = mongoose.model('User', UserSchema);
// 文章模型
const ArticleSchema = new Schema({
userId: { type: Schema.Types.ObjectId, ref: 'User' }, // 引用用户ID
title: { type: String, required: true },
content: { type: String, required: true }
});
const Article = mongoose.model('Article', ArticleSchema);
使用场景:
// 更新用户信息
async function updateUser(userId, newUsername) {
await User.findByIdAndUpdate(userId, { username: newUsername });
}
// 获取文章列表
async function getArticles() {
const articles = await Article.find().populate('userId'); // 使用populate自动填充用户信息
return articles.map(article => ({
...article.toObject(),
username: article.userId.username
}));
}
解决方案二:使用嵌入式文档
如果我们不希望每次都去查询数据库,可以选择将用户信息嵌入到文章文档中。这样,即使用户信息发生变化,我们也需要手动更新所有相关的文章。
示例代码:
const ArticleSchema = new Schema({
user: {
id: { type: Schema.Types.ObjectId, ref: 'User' },
username: { type: String, required: true }
},
title: { type: String, required: true },
content: { type: String, required: true }
});
使用场景:
// 更新用户信息
async function updateUser(userId, newUsername) {
await User.findByIdAndUpdate(userId, { username: newUsername });
await Article.updateMany({ 'user.id': userId }, { $set: { 'user.username': newUsername } });
}
这两种方法各有优缺点,具体选择哪种取决于你的应用场景和需求。第一种方法(引用)更灵活,而第二种方法(嵌入)在某些情况下可以提高性能。
我觉得存id再获取id对应的信息这个方法是合理的。相当于Mongoose的populate, 数据量大时可能会查询慢。 但是用户信息完全可以用Memcache或者Redis缓存下来,这样理论上查询会比较快,但是在数据量还不大时没必要这样做。
感觉到性能瓶颈了,再优化这地方,否则还是以维护性优先。 同时更新两个表,你是不是还得实现事务管理,万一失败记得回滚
请使用 sql。
不同用户发的文章列表很简单啊,你只要把文章先查出来,然后把用户id收集起来,一次性查出来。
而且我觉得mongoose的populate可能有类似的优化哟,这样你就可以直接用populate了,只用读两次数据库而已啦,别这么爱护你的服务器。。。
这样你不觉得数据冗余吗?
既然用了mongodb,那么就只能承担no sql带来的特性
对于这个问题,可以使用MongoDB的引用或者嵌入的方式来实现数据同步。
方案一:使用引用
在B表中保存A表中的用户ID,而不是用户名。当需要显示用户名时,再根据用户ID去查询A表中的用户名。
示例代码:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: String,
// 其他字段
});
const articleSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
content: String,
// 其他字段
});
const User = mongoose.model('User', userSchema);
const Article = mongoose.model('Article', articleSchema);
// 添加文章时
async function addArticle(userId, content) {
const user = await User.findById(userId);
if (!user) throw new Error('User not found');
const article = new Article({ userId, content });
await article.save();
}
// 获取文章列表并显示用户名
async function getArticles() {
const articles = await Article.find().populate('userId', 'username');
return articles.map(article => ({
...article.toObject(),
username: article.userId.username
}));
}
方案二:使用嵌入
在B表中直接嵌入A表的用户名,但这种方法不推荐,因为如果A表中的用户名发生变化,B表中的数据不会自动更新。
总结
方案一(使用引用)是更推荐的方式,因为它可以在保证性能的同时保持数据的一致性。通过使用populate
方法,可以在查询时动态地加载关联的数据,避免每次都去查询A表。