MongoDB 中的子结构与平面数据结构 - NoSQL
Sub-structures vs Flat Data-Structure in MongoDB - NoSQL
我试图了解如何最好地构建 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.I中提供了各种数据建模模式和模式设计,将分享我遇到的问题以及不同数据库模式的好处。下面我们一一讨论:
嵌入式 VS 平面数据结构: 在这种情况下,两种模式之间没有太大区别,但在嵌入式数据模型的情况下,我们是对相似类型的数据进行分组,这样可以使您的查询更简单或规模更小,同时您将从任何集合中 $project 数据。
例如:如果您想获取完整的地址,那么在嵌入式文档的情况下,您不需要单独 $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" } }
)
要更新嵌入一对多关系的数据,您需要使用 $ 运算符。在这一个中有两种不同的情况。首先,如果你想更新子文档的特定元素,其次如果你想更新所有子文档:
案例 1 查询将是(使用 $ operator):
db.collection.update(
{ 'address.streent': 'abc' },
{ $set: { "address.$.street": "xyz" } }
)
案例 2 查询将是(使用 $[]):
db.collection.update(
{ 'address.streent': 'abc' },
{ $set: { "address.$[]": "xyz" } }
)
我试图了解如何最好地构建 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.I中提供了各种数据建模模式和模式设计,将分享我遇到的问题以及不同数据库模式的好处。下面我们一一讨论:
嵌入式 VS 平面数据结构: 在这种情况下,两种模式之间没有太大区别,但在嵌入式数据模型的情况下,我们是对相似类型的数据进行分组,这样可以使您的查询更简单或规模更小,同时您将从任何集合中 $project 数据。
例如:如果您想获取完整的地址,那么在嵌入式文档的情况下,您不需要单独 $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" } }
)
要更新嵌入一对多关系的数据,您需要使用 $ 运算符。在这一个中有两种不同的情况。首先,如果你想更新子文档的特定元素,其次如果你想更新所有子文档:
案例 1 查询将是(使用 $ operator):
db.collection.update(
{ 'address.streent': 'abc' },
{ $set: { "address.$.street": "xyz" } }
)
案例 2 查询将是(使用 $[]):
db.collection.update(
{ 'address.streent': 'abc' },
{ $set: { "address.$[]": "xyz" } }
)