我需要使用Spring Data为MongoDB中的用户存储朋友关系。我的“架构”解决方案是在用户文档中存储朋友的用户名(也是_id)。我没有使用DBRef,因为在自我关系上Spring Data和DBRef似乎存在问题(朋友是用户:p)。一个简单的用户文档是这样的:
{
"_id" : "user1",
"email" : "user1@test.com",
"friendRequests" : {
"user4" : 0
},
"friends" : ["user2", "user3" ],
"password" : "$2a$10$9iJWLZjBSu3rq19wh7KTduNXIVcXozsNVjwVogO9eoz0uXO52Z2NC"
}
我认为这个模型足够好了。但是当有人接受朋友请求时,我必须更新两个用户的文档,并且操作不是原子操作。可能存在某些情况,其中只有一个得到更新。这不是关键数据,但仍然很乐意为此提供解决方案。我是否想过这个?我在2阶段提交http://cookbook.mongodb.org/patterns/perform-two-phase-commits/上发现了这个文档,但对于这种情况来说似乎太过分了,尽管它很容易实现。
答案 0 :(得分:1)
在不知道您的应用程序将如何使用数据的情况下,很难回答这些类型的问题。请记住,在MongoDB中,有许多不同的方法来表示基本相同的数据/模式,因此最适合您的应用程序的方式是满足您的应用程序需求的方式。
要问自己一些问题:
你知道每个用户平均有多少朋友吗?
您将如何显示/查询/更新用户的朋友?
上述哪些操作需要具有高性能且绝对最新,哪些操作可能需要更长时间,或者以后的批处理模式完成?
对于您的数据,每种可能的架构都需要权衡。不断地将用户名添加到每个用户的朋友阵列中意味着文档将不断增长(这对于高性能更新来说是次优的,因为当文档超过其分配的空间时,它需要在下次更新时移动)。为了抵消这种情况,您必须考虑以这种方式存储朋友数组时获得的收益。在获取有关用户的所有信息时,它是否允许您只进行一次读取?或者你还需要再次阅读(可能会再次查询用户集合,以获取有关Friends数组中每个用户的其他信息吗?
您已经在考虑更新的原子性,这有助于保持数据的一致性,但正如您正确指出的那样,这是您的应用程序可以处理的内容(或者您可以拥有运行并检测任何“部分方式”的后台作业友谊更新并清理它们。)
您还应该考虑如何索引集合 - 如果您需要在单个集合上使用多个索引来满足查询的SLA,那么您的更新/插入必然会变慢(因为需要更多的索引)得到更新)。这可能没问题,但只有你能做出有关权衡的决定。
我希望这会有所帮助。