我想要有关MongoDB模式设计的最佳实践建议。 我正在创建一个项目经理。我希望用户能够创建任务,并将此任务与项目的某个阶段相关联。 我考虑了两种设计,各有利弊:
第一个设计是:
const ProjectSchema: new Schema ({
...
phases: [{
phase_id: String,
name: String,
status: String,
startDate: Date,
endDate: Date,
tasks: [{
task_id: String,
title: String,
description: String,
completed: { type: Boolean, default: 'false' },
...
}],
}]
...
});
这里的优点是我每个阶段都有任务,因此如果想要一个阶段的所有任务,查询将花费更少的时间来处理,因为我不必每次都想要某个阶段的任务时都进行过滤。但是,如果需要查询项目的所有任务,则需要获取所有阶段,然后获取进行两次查询的任务。
另一种设计是:
const ProjectScema: new Schema ({
...
phases: [{
phase_id: String,
name: String,
status: String,
startDate: Date,
endDate: Date,
...
}],
tasks: [{
task_id: String,
title: String,
description: String,
completed: { type: Boolean, default: 'false' },
phase: { id: mongoose.Types.ObjectId, name: String },
...
}],
...
});
在这种情况下,更容易获得项目中分配的所有任务,但是如果我想要一个阶段的所有任务,则必须过滤任务数组。
在两种情况下,如果我都有大量任务,查询可能会很慢。我可以使用更好的设计吗?
另一种解决方案是将任务放在另一个集合中,并在各个阶段中对任务进行引用:
const TaskSchema: new Schema({
task_id: String
title: String,
description: String,
startDate: Date,
endDate: Date,
project_id: String,
phase_id: String,
...
});
TaskSchema.index({ task_id: 1 });
TaskSchema.index({ project_id: 1 });
const Task = mongoose.model('Task', TaskSchema);
在shcema项目中:
const ProjectScema: new Schema ({
project_id: String,
...
phases: [{
phase_id: String,
name: String,
status: String,
startDate: Date,
endDate: Date,
tasks: [{
type: Schema.Types.ObjectId,
ref: 'Task'
}],
...
}]
...
});
这样,由于索引,我可以查询项目的所有任务,也可以由于填充而获得阶段的所有任务。 我不知道哪种解决方案最适合使用,因为我会经常读写任务和阶段,并且可能会有大量的阶段和任务(1-2百个)。