当前位置:  开发笔记 > 编程语言 > 正文

社交网络的"架构"设计

如何解决《社交网络的"架构"设计》经验,为你挑选了1个好方法。

我正在为一个拥有约500,000用户的推特式社交网络开发一个概念证明应用程序.我不确定如何最好地设计'架构'

我应该嵌入用户的订阅还是拥有单独的"订阅"集合并使用数据库引用?如果我嵌入,我仍然需要执行查询以获取所有用户的关注者.例如

鉴于以下用户:

{
 "username" : "alan",
 "photo": "123.jpg",
 "subscriptions" : [
    {"username" : "john", "status" : "accepted"},
    {"username" : "paul", "status" : "pending"}
  ]
}

为了找到所有阿兰的订阅者,我必须运行这样的事情:

db.users.find({'subscriptions.username' : 'alan'});

从性能的角度来看,是否比拥有单独的订阅集合更糟或更好?

此外,当显示订阅/订阅者列表时,我目前遇到n + 1问题,因为订阅文档告诉我目标用户的用户名,但不是我可能需要的其他属性,例如个人资料照片.是否有针对此类情况的推荐做法?

谢谢艾伦



1> daveslab..:

首先,你应该知道你将通过MongoDB和任何其他NoSQL数据库获得的权衡(但我意识到我是它的粉丝).如果您试图完全规范化数据,那么您就犯了一个大错误.即使在关系数据库中,您的应用程序越大,您的数据被非规范化的次数就越多(请参阅Hot Potato的这篇文章).我一次又一次地看到了这一点.你不应该疯了,弄得一团糟,但不要担心在两个地方重复信息.NoSQL的一个主要观点(在我看来)是你的架构进入你的代码而不仅仅是数据库.

现在,为了回答你的问题,我认为你最初的策略是我会做的.MongoDB可以将索引放在数组元素上,这样如果您正在寻找用户拥有多少友谊,这将使事情变得更快.但实际上,真正确定的唯一方法是运行某种测试程序,生成一个充满名称和关系的数据库.

您可以使用Python或Perl或任何您喜欢的内容编写一些输入脚本,并使用名称文件生成一些关系.查看人口普查网站,其中包含姓氏列表.下载文件dist.all.last并编写一些程序,如:

#! /usr/bin/env python
import random as rand

f = open('dist.all.last')
names = []
for line in f:
  names.append(line.split()[0])

rels = {}
for name in names:
  numOfFriends = rand.randint(0, 1000)
  rels[name] = []
  for i in range(numOfFriends):
    newFriend = rand.choice(names)
    if newFriend != name: #cannot be friends with yourself
      rels[name].append(newFriend)

# take relationships (i.e. rels) and write them to MongoDB

另外,作为一般说明,您的字段名称似乎有点长.请记住,字段名与该集合中的每个文档都重复,因为您不能依赖于任何其他文档中的一个字段.为了节省空间,一般策略是使用较短的字段名称,如"unam"而不是"username",但这是一件小事.看看这 两篇文章中的好建议.

编辑:

实际上,在进一步思考你的问题时,我会再提出一个建议:将订阅类型分解到不同的字段以使索引更有效.例如,而不是:

{
 "username" : "alan",
 "photo": "123.jpg",
 "subscriptions" : [
    {"username" : "john", "status" : "accepted"},
    {"username" : "paul", "status" : "pending"}
  ]
}

如上所述,我会这样做:

{
 "username" : "alan",
 "photo": "123.jpg",
 "acc_subs" : [ "john" ],
 "pnd_subs" : [ "paul" ]
}

因此,您可以为每种类型的订阅设置一个索引,从而进行"Hoy很多人让Paul等待处理"这样的查询.和"有多少人订阅保罗?" 无论哪种方式超快.Mongo对数组值的索引确实是史诗般的胜利.


不错的帖子,+1,但我不同意简短的名字.只要有必要就制作它们,不必向其他开发者解释任何内容.然后根据需要进行分析/优化.如果你缩放名称是一个重要的问题,那么重构.
推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有