在使用 NoSQL 数据库时,这会被认为是错误的方式吗?在使用 NoSQL 时,我不应该考虑“关系”吗?
关于嵌入的问题有很多,归结为很少。
如果您希望嵌入,此处未提及的内容需要考虑:
- 文档大小会大幅增加吗?如果是这样,那么文档可能会经常在磁盘上移动,这是一件坏事。
- 相关行是否会与我正在处理的集合有很多连接(即
video
不能嵌入user
)。如果是这种情况,您在将冗余数据从相关行复制到子文档时可能会遇到问题,尤其是在更新该冗余数据时。
- 我需要如何显示这些结果?
显示结果始终是是否嵌入的关键决定因素。如果您需要对大量行(例如 1000 行)进行分页,则需要$slice
在普通查询或聚合框架中使用该运算符。在 1000 时,我承认它可能非常快,但内存中的操作迟早会比正常查询慢(事实上它总是应该如此)。
如果您需要对子文档进行复杂的排序和显示,您可能希望将它们拆分出来,而是具有以下文档结构:
{
"string": "foobar",
"owners": [
ObjectId(),
ObjectId(),
ObjectId()
]
}
我认为这对于您的数据实际上可能是一种性能更高的结构,因为owner
听起来像是集合user
中的一行。users
您可以参考他们的_id
. 这很酷,因为您可以嵌入关系,但同时文档只会增长很少,这希望意味着磁盘不断移动的可能性很小,不仅如此,而且更小的工作集可以创建整体上更高性能的操作。不仅如此,当然_id
所有者的身份很少会改变,因此您最有可能需要对这个数据子集进行的唯一操作就是创建和删除。
回到复杂的排序和分页。有了这些数据,您当然可以owner
通过一次往返获取所有 ID,然后在另一次往返中,您可以users
使用$in
允许您需要的复杂显示的正常查询来查询表中的那些所有者行。
所以我发现这个结构总体上是非常高效的。
当然,这种结构取决于您的查询,最好将字符串 id 存放在用户身上,但在这种情况下它不会,因为用户可能可以拥有许多字符串,因此我会说它是一个多->多嵌入在字符串端的关系。
希望这会有所帮助,而且我没有绕圈子,