在设计SQL数据库时,有一些明确的规则(规范化规则)。
所以,鉴于这个模型:
在SQL中以这种方式设计它很容易,有两个表:
Places(placeId, name, lat, lng)
Events(eventId, placeId, name, startDate, endDate)
这是不正确的,这是正确的。没有多少选择......
通过这种设计,我有一些好处:
现在,我正在尝试在MongoDb中设计相同的模型,我不确定它,因为有很多替代方法可以实现这一目标:
两个集合:不包含事件的地方,以及不包含地点的事件(但保留placeId字段)
var placeSchema = new mongoose.Schema({
name: String,
lat: Number,
lng: Number,
});
var eventSchema = new mongoose.Schema({
name: String,
startDate: Date,
endDate: Date,
placeId: mongoose.Schema.Types.ObjectId,
});
两个集合:包含事件的地方和不包含地点的事件(但保留placeId字段)
var placeSchema = new mongoose.Schema({
name: String,
lat: Number,
lng: Number,
events: [eventSchema]
});
var eventSchema = ...
两个集合:包含事件和包含地点的事件的地方(不同文档中的重复数据)
包含活动的一个地方集合
var placeSchema = new mongoose.Schema({
name: String,
lat: Number,
lng: Number,
events: [eventSchema]
});
在上述所有选择中,我可以想象出麻烦。如果我需要更新名称(作为地名或事件名称),我需要在多个文档中更新它。例如,在“一个地方集合”方法中,一个事件不包含一个地方..所以如果我将一个事件对象单独传递给我的视图,那么该视图将不会知道包含该事件的地方! / p>
所以,我的问题是两个:
此型号的优秀设计是什么?
我为了这篇文章简化了模型..但实际上事件有标签,事件和地方都有图片。我可以在这里描述整个模型,但这将是滥用。 我想知道设计mongoDB数据库(基于文档的数据库)的规则。规范化规则清楚地说明了如何应用它们以及它们的好处(主要是维护,例如更新时的干净代码等)。 这里有明确的规则吗?。此外,这些(规范化)规则非常直观,通过跳过文献,无论如何都可以采用正确的方式。
答案 0 :(得分:1)
嗯,这实际上取决于您对架构的要求。
首先要做的事情:您为"两个集合编写的代码:包含事件的地方,以及不包含地点的事件(但保留placeId字段)"应该这样:
var placeSchema = new mongoose.Schema({
name: String,
lat: Number,
lng: Number,
events: [mongoose.Schema.Types.ObjectId]
});
var eventSchema = ...
因为mongodb没有加入,所以通常你必须进行非规范化,直到你有充分的理由进行规范化。
在您想要做的事情中,如果您的地方可能有很多活动,那么以分页模式或类似的方式获取事件会让您的查询变小。在那种情况下,我更喜欢"两个集合:包含事件的地方,以及不包含地点的事件"。 但是如果你的地方最多只有几个活动,我会将它们全部保存在一个系列中。 此外,如果您想直接访问事件,最好将它们分成两个集合,如果需要,可以在事件集合中放置地名和_id(不要太担心重复,大多数情况下都是如此) ,速度和小查询是你必须关心的。)
对于更新,mongodb提供了更新的好工具。例如,如果您很少进行更改(例如更改地名),请不要将其标准化。
还有一件事,mongoose提供了很好的工具,例如population。