如何在MongoDB中关联数据?
我正在数据库中存储一个字符串以及该字符串的所有者(每个字符串有一个或多个所有者) 我一直使用MySQL,这是一种传统的关系数据库。在这种情况下,我将在一个表中存储字符串和唯一id,然后在第二个表中存储字符串的唯一id和所有者(作为多条记录) 然后,我可以通过所有者使用SQL连接获取字符串 我现在正在使用MongoDB进行一个项目,我正在做与上面相同的事情 在使用NoSQL数据库时,这会被认为是错误的方法吗?在使用NoSQL时,我不应该考虑“关系”吗 在MongoDB中实现同样功能的另一种方法是将其存储如下:如何在MongoDB中关联数据?,mongodb,nosql,Mongodb,Nosql,我正在数据库中存储一个字符串以及该字符串的所有者(每个字符串有一个或多个所有者) 我一直使用MySQL,这是一种传统的关系数据库。在这种情况下,我将在一个表中存储字符串和唯一id,然后在第二个表中存储字符串的唯一id和所有者(作为多条记录) 然后,我可以通过所有者使用SQL连接获取字符串 我现在正在使用MongoDB进行一个项目,我正在做与上面相同的事情 在使用NoSQL数据库时,这会被认为是错误的方法吗?在使用NoSQL时,我不应该考虑“关系”吗 在MongoDB中实现同样功能的另一种方法是将
{
"string": "foobar",
"owners": [
"owner1",
"owner2",
"owner3"
]
}
但是,在这种情况下,我不确定如何搜索“owner1拥有的所有字符串”。这看起来是正确的方法;但请记住,这始终取决于项目的总体情况、目标(性能、灵活性)、最需要运行的查询、是否需要运行特别查询以及其他因素。但一般来说,使用嵌套文档(如您所写)是使用联接和外键的正确替代方法
还请记住(目前为16MB),如果给定字符串的拥有者很多(比如数十万),那么这将是一个问题。为了补充dbaseman的答案: 是的,你的方法似乎还可以。您可以轻松搜索“owner1拥有的所有字符串” 这是可能的,因为mongodb以一种特殊的方式处理数组 在使用NoSQL数据库时,这会被认为是错误的方法吗?在使用NoSQL时,我不应该考虑“关系”吗 关于嵌入的问题有很多,但归结起来却很少 如果您希望嵌入以下内容,则需要考虑此处未提及的事项:
- 文档大小是否会大幅增加?如果是这样,那么文档可能会频繁地在磁盘上移动,这是一件坏事
- 相关行是否有多个连接到我正在处理的集合(即,
无法嵌入视频
)。如果是这种情况,则在将冗余数据从相关行复制到子文档中时可能会遇到问题,尤其是在更新该冗余数据时用户
- 我需要如何显示这些结果
$slice
操作符。在1000点时,我承认它可能相当快,但内存中的操作迟早会比正常的查询慢(事实上它总是应该的)
如果您需要对子文档进行复杂的排序和显示,您可能希望将这些子文档拆分出来,并采用以下文档结构:
{
"string": "foobar",
"owners": [
ObjectId(),
ObjectId(),
ObjectId()
]
}
我认为这实际上对您的数据来说可能是一个性能更高的结构,因为所有者
听起来像用户
集合中的用户
行
您可以只引用用户的\u id
,而不必使用可能更改的数据填充子文档。这是非常可笑的,因为您可以嵌入关系,但同时文档只会增长很小,这意味着持续磁盘移动的可能性很低,不仅如此,还意味着更小的工作集创建了更高性能的总体操作。不仅如此,当然所有者的\u id
很少会改变,因此您最有可能抛出此数据子集的唯一操作就是创建和删除
回到复杂的排序和分页。有了这些数据,您当然可以通过一次往返获得所有所有者
ID,然后在另一次往返中,您可以使用用户
表中的$in
进行正常查询,从而实现所需的复杂显示
因此,我发现,这种结构总体上是非常有效的
当然,这种结构取决于您的查询,最好将字符串id放在用户身上,但在本例中,情况并非如此,因为用户可能拥有许多字符串,因此我会说,这是一种嵌入在字符串端的多->多关系
希望这会有所帮助,而且我没有兜圈子,在处理嵌入式数据时,我建议大家熟悉mongo中的原子性行为。 一个好的起点是: 在向“所有者”数组添加/删除用户ObjectId(Sammaye建议)的特定情况下,您需要对字符串文档使用操作,以确保在多次写入该文档时,仍然保持数据完整性 在此操作中,我建议使用以下操作符:
请不要将“NoSQL”用作保护伞。你在使用MongoDB。就这样。“NoSQL”的意思是太多太少:-)谢谢。我不必担心文档的最大大小,因为我不会接近它。我最常见的查询是insert。非常非常少的发现。
{
"string": "foobar",
"owners": [
ObjectId(),
ObjectId(),
ObjectId()
]
}