我正在做我的第一个NoSql设计,需要一些关于规范化多少的帮助。
我有一个简单的关系数据库:
Users (Id, UserName, Password, Email, Name, FacebookId, DateCreated)
Questions (Id, UserId, Question, DateCreated)
Answers (Id, QuestionId, Answer, DateCreated)
我想将其转换为Mongoose模式。我不确定我要嵌入多少,我要参考多少。以下是我的一些想法:
只有一个集合Users,并将所有内容嵌入其中:
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' }}] }]
});
有两个集合(我将限制答案数量的最大#为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 (userId)
- GetAllAnswersAnsweredByUser (userId)
给定最后两个查询,在Users集合中保留对问题的引用以实现更快的访问是否有意义?
有对User表中的Questions and Answers的引用:
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' }] });
我想的方向对吗?在我的场景中,哪种模式是最好的选择?
我喜欢你对这个问题的思考和分析方式。
需要考虑的是磁盘上的记录是一个接一个地放置的。如果您将所有内容存储在一个集合中,并且问题和答案是可以增长的数组,那么一旦记录之间没有空间可以添加另一个问题/答案,则必须移动记录—导致磁盘文件碎片。您可以在记录之间预先分配填充以实现增长,但这会浪费磁盘空间。所以这种方法已经过时了。我在想的另一件事是,最有可能的是,你不会显示没有答案的问题——或者你可能会显示一个问题列表,每个问题有前2-3个答案——所以这就像一个混合方法,问题集合将有3个答案驻留在一个数组中——没有碎片,其余的答案在一个单独的集合中。或者,您已经提到将把答案的数量限制为10个——因此,您可以预先分配10个"虚拟"答案,以避免碎片化(以磁盘空间为代价)。总而言之,我将使用一个User集合,一个questions集合,其中每个问题记录都有一个指向提出问题的用户的字段,或者使用带有单独答案集合的混合问题/答案方法,或者使用一个问题/答案集合,其中答案数组限制为10。