从 SQL Server DB 迁移到 MongoDB:关于是嵌入还是引用的问题

Posted

技术标签:

【中文标题】从 SQL Server DB 迁移到 MongoDB:关于是嵌入还是引用的问题【英文标题】:Migrating from SQL Server DB to MongoDB: questions about whether to embed or to reference 【发布时间】:2014-09-18 21:46:35 【问题描述】:

我正在研究我的第一个 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'  )  );

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

获取所有用户 获取所有问题 GetAllQuestionsWithAnswers GetAllQuestionsAskedByUser(userId) GetAllAnswersAnsweredByUser(userId)

鉴于最后两个查询,在用户集合中保留对问题的引用以加快访问速度是否有意义?

参考用户表中的问题和答案:

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】:

我喜欢你用于解决问题的思考和分析方式。 要考虑的事情是磁盘上的记录是一个接一个地布置的。如果您将所有内容存储在一个集合中,并且问题和答案是可以增长的数组,那么一旦记录之间没有空间来添加另一个问题/答案,则必须移动记录 - 导致磁盘文件碎片。您可以在记录之间预先分配填充以实现增长,但这会浪费磁盘空间。所以这种方法已经过时了。 我在想的另一件事是,最有可能的是,您不会显示没有答案的问题——或者您可能会显示一个问题列表,其中每个问题都有前 2-3 个答案——这就像一个混合方法,其中问题集合每个问题将有 3 个答案驻留在一个数组中——没有碎片,其余的答案在一个单独的集合中。或者,您已经提到您会将答案的数量限制为 10 - 所以也许您可以预先分配 10 个“虚拟”答案并避免碎片(以磁盘空间为代价) 总之,我会使用一个 User 集合,一个 Questons 集合,其中每个问题记录都有一个指向提出它的用户的字段,以及具有单独 Answer 集合的混合问题/答案方法,或一个 Question/Answer 集合其中答案数组限制为 10。

【讨论】:

感谢您的建议。我是否还应该在 Users 表中保留对 Questions 集合(QuestionIds 数组)的引用,以便轻松查找用户提出的所有问题?这是正常的事情吗?有什么好处吗? 好吧,您保留的内容的详细信息取决于查询 - 从小处着手,然后逐渐调整,直到获得所需的内容。这就是 MongoDB 的优点——迭代开发。

以上是关于从 SQL Server DB 迁移到 MongoDB:关于是嵌入还是引用的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何从Oracle 迁移到 Mongo DB

将本地 mongo db 迁移到 atlas 后无法从 atlas 获取记录

数据从SQL Server迁移到Azure Cosmos数据库后无法查看数据

从 Access 迁移到 SQL Server 数据库

从 SQLite 导出到 SQL Server

从 mongo 导出然后导入 SQL Server 时出现问题