【发布时间】:2017-07-06 07:45:17
【问题描述】:
在设计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] });
在所有上述替代方案中,我可以想象麻烦。如果我需要更新一个名称(作为地名或事件名称),我需要在多个文档中更新它。例如,在“一个地点集合”方法中,一个事件不包含一个地点。所以如果我将一个事件对象单独传递给我的视图,视图将不知道包含该事件的地点的任何信息!
所以,我的问题有两个:
什么是这个模型的好设计?
为了这篇文章,我简化了模型。但实际上事件有标签,事件和地点都有图片。我可以在这里描述整个模型,但那将是滥用。 我想知道设计 mongoDB 数据库(基于文档的数据库)的规则。规范化规则清楚地说明了如何应用它们以及它们有什么好处(主要是维护,例如更新时的干净代码等)。 这里有明确的规定吗?。此外,这些(规范化)规则非常直观,通过跳过文献,无论如何都可以以正确的方式做到这一点。
【问题讨论】:
-
您的数据似乎是关系型的,因为您想以多种方式查询它,为什么要迁移到 NoSQL?
-
@AkerbeltZ 是啊.. 发完这篇文章并阅读了几篇文章后,我想我毕竟会使用 SQL ......我只是想学习 mongodb,块上的新手等。还有每次我google nodejs时,mongodb+mongoose都会出现,就像他们住在一起一样
-
我一开始也犯了同样的错误,然后回到SQL。我认为 NoSQL 是数据库市场的绝佳补充,但明智地使用它很重要。
-
@AkerbeltZ 我认为我没有对 cmets 给予足够的关注,例如“对非关系数据有好处”、“当你不需要连接时很好”等。我现在看到它们是相当字面的.
标签: node.js mongodb mongoose nosql