我试图了解如何最好地构建mongoDB模式,因此请寻找指导,尤其是在使用子结构(嵌入式文档)与平面数据结构时。
让我们想象我们要在MongoDB中存储一个用户帐户。用户只有一个地址,因此我们可以选择以下两个结构之一:
{
_id: String,
username: String,
firstname: String,
surname: String,
email: String,
street: String,
city String,
zip: Number,
}
或
{
_id: String,
name: {
first: String,
last: String,
}
email: String,
address: {
street: String,
city String,
zip: Number,
}
}
每个结构的优点/缺点是什么?是否有何时使用子结构或何时使用平坦结构的规则?一个对另一个的原因是什么?
预先感谢您!
MongoDB中提供的各种数据建模模式和模式设计。我将分享我的经验,我遇到的问题以及不同DB架构的好处是什么。我们将在下面逐一讨论:
-
嵌入式与平面数据结构:在这种情况下,这两种模式之间并没有太大差异,但是如果以嵌入式形式进行数据模型,我们正在分组类似的数据,以便使您的查询尺寸有些简单或小,而您将从任何集合中$项目数据$。
例如:如果要获取完整的地址,则在嵌入式文档的情况下,您不需要单独$ project地址字段,如果您想在获取文档时跳过地址字段,则无需跳过地址字段单独。
-
嵌入式(一对一)vs嵌入式(一对数):在讨论有关平面数据结构的嵌入式文档的好处,但如果我们的用户有更多一个地址然后我们需要使用一对多关系的嵌入式文档。
定义一对一和多个关系的架构如下:
一对一的关系模式:
{
_id: String,
name: {
first: String,
last: String,
}
email: String,
address: {
street: String,
city String,
zip: Number,
}
}
一到许多关系模式:
{
_id: String,
name: {
first: String,
last: String,
}
email: String,
address: [{ // Embedded address doc with one to many relationship
street: String,
city String,
zip: Number,
}]
}
如果一对一的关系,它不会太多影响您的查询部分,但是如果您使用一到多个关系,则查询会有许多概念上的变化。
例如:由于我们在更新两种数据结构时主要面临不同的方案,因此我将分享更新查询之间的区别。
要更新嵌入一对一关系的数据,您可以简单地使用点表示法。
db.collection.update(
{ _id: 'anyId' },
{ $set: { "address.street": "abc" } }
)
要更新嵌入的数据,其中需要一到许多关系,您需要使用$ operator。在这种情况下,有两种不同的情况。首先,如果要更新子图表的特定元素,第二个如果要更新所有子图表:
案例1查询将是(使用$ operator):
db.collection.update(
{ 'address.streent': 'abc' },
{ $set: { "address.$.street": "xyz" } }
)
案例2查询将(使用$ []):
db.collection.update(
{ 'address.streent': 'abc' },
{ $set: { "address.$[]": "xyz" } }
)