ruby-on-rails - 在我的数据库中存储用户的Facebook friend 列表的最佳方法是什么?

标签 ruby-on-rails database facebook facebook-graph-api

概述
我正在创建一个ruby on rails网站,它使用facebook登录。
对于每个用户,我都有一个数据库条目,其中存储了他们的facebook用户id和其他基本信息。
我也在使用考拉宝石,以便从Facebook检索用户的好友列表,但我不确定我应该如何存储这些数据…
选择1
我可以将用户的朋友存储为User表中的序列化散列,然后如果我想显示当前用户的所有朋友的列表,我可以获取此散列并按照SELECT FROM Users WHERE facebook_user_id IN hash的行执行一些操作。
每次用户登录时,我都可以更新此字段以存储最新的朋友列表。
选择2
我可以在这里创建一个好友表并存储好友信息,用户有很多好友。所以每个友谊都有一行,(User1User2列)。然后,要显示当前用户的朋友列表,我可以执行类似SELECT User2 FROM Friends WHERE User1 = current_user
对我来说这似乎是个更好的选择,但是…
它的缺点是会有很多行…如果有100000个用户,每个用户有100个朋友,那么现在就有10000000行在friends表中。
这也意味着每次用户登录时,如果他们的好友列表中有人在我的用户表中,而好友表中没有相应的条目,我需要循环使用考拉返回的Facebook好友列表,并创建好友记录。如果一个用户有1000个facebook好友,这看起来会很慢?
我很感激你的指导,告诉我怎样才能最好地做到这一点。
对于这个措辞不好的问题,我深表歉意,我会尽快改写/整理它。
谢谢你事先的帮助。

最佳答案

如果你需要存储大量的数据,那么你需要存储大量的数据。如果你和大多数人一样,你可能不会在有钱解决问题之前就遇到这个问题。换句话说,至少在短期内,你可能假设你的流量和数据比你得到的要多。所以我怀疑这是一个问题,尽管这是一个好兆头,表明你正在考虑它现在而不是以后。
正如我在下面的评论中提到的,最简单的解决方案是为朋友关系的每一方都有一个带行的领带表(根据下面提到的设计,facebookfriend上的ahas_many :friends, through: :facebook_friend_relationships, class_name: 'FacebookFriend')。但你的问题似乎是关于如何减少记录的数量,所以这就是剩下的答案将要解决的问题。
如果你必须存储在数据库中,并且你确定你绝对会让这个星球上的每个FB用户都访问你的站点,因为它太棒了,但他们不会一次全部命中,那么如果你的存储空间有限,你可能会想使用一个LRU算法(删除最近使用最少的记录),可能还有定时过期。您可以让cron作业在数据库上执行查询,然后删除旧的/未使用的记录来执行此操作。不是完美的,但这是一个简单的解决方案。
你也可以把旧的数据存档,而不是扔掉。因此,经常使用的数据可能会留在活动用户的表中,然后您可能会将较旧的数据卸载到另一个表甚至另一个数据库中(您可能会看到公寓和第二个基础gem)。然而,一旦达到这个规模,您可能会看到许多与activerecord模型/关联或模式设计关系不大的其他架构解决方案。尽管提前计划是值得的,但在您确信应用程序将获得足够的用户来投入时间之前,我不会过分担心这一点。
尽管activerecord有一些缓存,但是为了提高速度,您可以在一开始就避免数据库和缓存朋友,特别是如果您还没有很多用户,而您可能还没有。如果您认为由于用户太多而导致内存不足,那么lru可能也是一个不错的选择,而且lru_redux看起来很有趣。同样,您可能还希望对缓存进行计时,以便在缓存过期时重新获取好友。即使只是将结果存储在用户会话中也可能是足够的,即在控制器操作方法中,只需执行@friends ||= Something.find_friends(fb_user_id),后者是大多数人在开始时可能会执行的第一个操作。
如果使用activerecord,则在控制器中的查询(或模型中的关联)中考虑使用include:来避免n+1查询。这会加快速度。
对于架构设计,可能:
带有电子邮件和身份验证信息的用户表。看这宝石。
facebook用户-关于facebook用户的信息。
FacebookFriendRelationship——一个具有(id和)两列的领带模型,一个用于一个FacebookUserID,另一个用于另一个。
通过将authn info(user)与fb数据(facebook user和facebook friendrelationship)分离,可以更轻松地拥有其他社交媒体帐户等,每个帐户都有其他表中特定于这些帐户的信息。
如果目标是最小化关系表中的行,那么FACKBooRead与朋友之间的关系就复杂了。如果要将行数减少一半,那么对于facebook用户的id可以在任意一个外键列中的关系,就只有一行。用户有朋友或是朋友,因此可以在facebookfriend上有两个has_many :through关联,每个关联在facebookfriendrelationship中使用不同的外键。或者您可以在没有模型的情况下执行habtm,并在每个关联中使用foreign_key和association_foreign_key选项。无论哪种方式,您都可以添加一个方法来将两个关联添加到一起(因为它们是数组)。相反,如果您不想使用activerecord以正常方式删除关联,则可以在单个has_many中使用自定义sql。但是,根据你的评论,我认为你想避免这种复杂性,我同意你的观点,除非你真的必须限制关系行的数量。然而,不是tie表行的数量会吃掉数据,而是保存在facebookfriends表中的所有用户信息。

关于ruby-on-rails - 在我的数据库中存储用户的Facebook friend 列表的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16597432/

相关文章:

ruby-on-rails - Rails 3,多对多形式使用accepts_nested_attributes_for,我该如何正确设置?

ruby-on-rails - Ruby on Rails 4-回形针AWS Image URL错误吗?

ruby-on-rails - Rails 3.1 按特定顺序加载 css

database - 平凡的 super 键可以被视为候选键吗?

facebook - Facebook offline_access 弃用的含义

ruby-on-rails - 将包含 AM/PM 的 12 小时时间字符串转换为 24 小时时间

sql-server - 在 SQL 中查询最小值、最大值、平均值和最后一个值

php - SQL/PHP : How to upload big database to server when I have import file size limit? 然后更新

node.js - Express 4.0 和 Passport - 重定向到 Facebook 不起作用

ios - Facebook SDK 登录 xcode 在获取 avater 时崩溃