从SQL Server数据库迁移到MongoDB:有关是嵌入还是引用的问题

时间:2014-07-27 16:09:19

标签: node.js mongodb mongoose mean-stack nosql

我正在开发我的第一个NoSql设计,需要一些帮助来规范化程度。

我有一个简单的关系数据库:

   Users (Id, UserName, Password, Email, Name, FacebookId, DateCreated)
   Questions (Id, UserId, Question, DateCreated)
   Answers (Id, QuestionId, Answer, DateCreated)

我希望将其转换为Mongoose架构。我不确定我需要嵌入多少以及我需要参考多少。以下是我的一些想法:

只有一个用户集合,并将所有内容嵌入其中:

mongoose.model('Users', {
        userName: String, 
        password: String,
        email: String,
        name: String,
        facebookId: String
        dateCreated: Date
        questions : [{ question: String, date: Date, answers: [{ answer: String, answeredByUserId: {type: Schema.Types.ObjectId, ref: 'User' }}] }]
    });

有2个集合(我将答案数量的最大数量限制为10个)

mongoose.model('Users', {   
    userName: String, 
    password: String,
    email: String,
    name: String,
    facebookId: String
    dateCreated: Date    });

mongoose.model('Questions', {   
    question: String, 
    dateCreated: Date,
    askedByUserId: {type: Schema.Types.ObjectId, ref: 'User' },
    answers: [{ answer: String, date: Date, answeredByUserId: {type: Schema.Types.ObjectId, ref: 'User' } }] }) });

有3个单独的集合(没有答案的限制):

mongoose.model('Users', {   
    userName: String, 
    password: String,
    email: String,
    name: String,
    facebookId: String
    dateCreated: Date    });

mongoose.model('Questions', {   
    question: String, 
    dateCreated: Date,
    askedByUserId: {type: Schema.Types.ObjectId, ref: 'Users' } })  });

mongoose.model('Answers', {     
    answer: String, 
    dateCreated: Date,
    answeredByUserId: {type: Schema.Types.ObjectId, ref: 'Users' }
    questionId: {type: Schema.Types.ObjectId, ref: 'Questions' } })  });

这些是我将要进行的查询:

  • GetAllUsers
  • GetAllQuestions
  • GetAllQuestionsWithAnswers
  • GetAllQuestionsAskedByUser(用户ID)
  • GetAllAnswersAnsweredByUser(用户ID)

鉴于最后两个查询,是否有必要在Users集合中引用问题以便更快地访问?

在用户表中引用问题和答案:

mongoose.model('Users', {   
    userName: String, 
    password: String,
    email: String,
    name: String,
    facebookId: String,
    dateCreated: Date,
    Questions: [{ type: Schema.Types.ObjectId, ref: 'Questions' }],
    Answers: [{ type: Schema.Types.ObjectId, ref: 'Answers' }]    });

我在思考正确的方向吗?在我的场景中,哪种架构是最佳选择?

1 个答案:

答案 0 :(得分:2)

我喜欢你正在应用这个问题的思维和分析方式 需要考虑的是磁盘上的记录是一个接一个地布局的。如果要将所有内容存储在一个集合中,并且问题和答案是可以增长的数组,那么一旦记录之间没有空格来添加另一个问题/答案,就必须移动该记录 - 导致磁盘文件碎片化。您可以在记录之间预先分配填充以进行增长,但这会浪费磁盘空间。所以这种方法已经出来了。 我想的另一件事是,最有可能的是,如果没有答案,你就不会显示问题 - 或者你可能会显示一个问题列表,每个问题有2-3个答案 - 所以这就像问题收集的混合方法每个问题将有3个答案驻留在一个数组中 - 没有碎片,其余的答案都在一个单独的集合中。或者,你已经提到你将答案数量限制为10 - 所以也许你可以预先分配10" dummy"提前回答并避免碎片(以磁盘空间为代价) 总之,我会选择一个User集合,一个Questons集合,其中每个问题记录都有一个字段指向已经询问它的用户,以及混合问题/答案方法与单独的答案集合,或者一个问题/答案集合答案数组限制为10。