【问题标题】:Send array items to server or query it on the server side?将数组项发送到服务器或在服务器端查询它?
【发布时间】:2014-04-18 09:59:59
【问题描述】:

这是我的方案,我正在尝试做更有效率的事情。

我有一个用户,其关注者范围从 100 到 5000 个不等(比最小值多或少)。用户和关注者计数本地存储在用户设备(Android - sqlite)上。

选项 A:当用户想要查看他的关注者时,我向要查询的 userId 的服务器 (node.js) 发送请求 (mongodb),然后对该用户的关注者数组中的所有用户进行另一个查询。

选项 B:让用户使用 userId 和关注者 ID 数组发送请求,然后向服务器查询一次以查找关注者。

A的效果:查询翻倍(因为followers数组必须先查询)

B 的影响:连接可能会丢失并且必须重新发送数据,并且可能是一次发送大量数据,必须调用 POST/PUT 而不是 GET(至少我认为我愿意)。

因素: - 用户体验 - 优先级 1 -服务器成本 - 优先级 2

编辑

说明:

这是指一位用户及其追随者。从登录时开始,我将关注者 ID 存储在 sqlite 的行中。

【问题讨论】:

  • 我在选项 A“他的追随者”中感到困惑 (1) - 他是拿着手机的用户吗?或手机持有者的关注者列表中的一位用户? (2) SQLite 数据库中究竟存储了什么?它是所有关注者的用户 ID 列表吗?还是只是追随者的数量?
  • 你最初是如何获得设备上关注者的 id 的?
  • 我在上面添加了说明......拿着手机的用户,以及所有 userIds 的列表(所以每个 id 都有一行)......@Benito 我在登录时存储它

标签: android node.js mongodb


【解决方案1】:

为什么一开始还要发送关注者 ID?

在登录响应中发送关注者 ID 是没有意义的。

让我们考虑一下这是您当前的登录响应:

{
  status:"success"
  data: {
          userId: "123456",
          firstName: "John",
          lastName: "Doe",
          followers: [ "111111", "222222", "333333", ... ]
        }
}

因此,您保存了关注者 ID。现在你将如何使用它们?

由于您没有发送姓名,因此您无法请求单个关注者个人资料,并且您不会向用户显示可供选择的关注者 ID 列表,因为他不知道他们正在选择哪个关注者。

因此,您必须至少为每个 id 添加一个关注者名称,这意味着一个非常大的响应,考虑到一个用户最多可以有 5000 个关注者。

在我看来,这对于登录 API 来说太过分了(即使没有名称)。

或者,您可以只发送关注者的数量。

{
  status:"success"
  data: {
          userId: "123456",
          firstName: "John",
          lastName: "Doe",
          followerCount: 2000
        }
}

现在,当用户决定查看他的关注者时,您只需发送他的用户 ID(选项 A),这足以查询他们。

我不熟悉面向文档的数据库,但我认为这样的查询不会有任何性能问题。

为什么不选择选项 B?

  1. 如前所述,登录 API 响应会非常大。
  2. 如果用户关注者在登录和第二个 API 之间发生变化怎么办?例如,您不会有新关注者的用户 ID。

最后一条建议

在您的响应中实现服务器端分页。

5000 是一个相当大的数字。如果没有分页,您的响应将会很大,并且某些设备可能没有足够的内存来存储它。

这是一个例子:

http://www.example.com/followers?userId=123456&pageSize=25

{
  status:"success"
  data: {
          followers: [
              {
                userId: "----",
                userName: "----",
                firstName: "----",
                lastName: "----",
                ImageUrl: "----"  
              },     
              {
                userId: "----",
                userName: "----",
                firstName: "----",
                lastName: "----",
                ImageUrl: "----"  
              }, 

             ...     
          ]
          paging: {
              page: 1, 
              pageSize: 25,
              previous: "",
              next:"http://www.example.com/followers?userId=123456&pageSize=25&page=2"
          }
        }
}

【讨论】:

  • 感谢伟大的帖子,我正在保存 id 以查看用户(A)是否会访问另一个用户的个人资料(B),我会请求查询搜索(B)然后我将检查 (A) 是否将 (B) 的用户 ID 存储在 sqlitedb 中 - 如果是,那么他正在关注他,如果没有,那么他可以关注他,这将被添加到他在 sqlite 中关注的人员列表中,而不是查询(B) 然后 (A) 的 db 并查看 (B) 的 id 是否与 (A) 数组中的 id 的以下匹配项列表匹配...然后每次用户决定添加或删除(B) 我不必一直提出请求。
  • 但是,我想我可以只包含新的关注/取消关注,如果它是
  • 关于您的第一条评论,当您请求其他用户的个人资料时,您可以发送一个布尔值 isFollower,指示此用户是否为关注者。
  • 您不必将页码与用户数相关联。我只是出于显示目的添加它:“您有 2000 个关注者”。
  • 哦,好吧,例如,每个页面 = 100 个用户 ID,然后提取用户 0-100,这就是您的操作方式,如果它达到某个数字,则使用某些公式调用第 2 页获得100-200的范围?因为我不能只添加总计数或其他东西并将其除以 100,然后根据计数询问每个索引范围,只是想知道它是如何工作的,因为当用户拉动并点击关闭时我将在 android 上实际执行它到 100 我需要更多
【解决方案2】:

为了有效地解决这个问题,我将实现一个缓存键,将其存储在 mongodb 和 android 设备中。每当一个人的追随者发生变化时,都会重新生成缓存键。该键在 mongodb 中建立索引,以便快速查找。

当我想查看我的一个关注者时,我会发送关注者 ID 和缓存键。如果密钥匹配,则设备具有最新数据,因此您可以发回“chache valid”响应。如果不匹配,则设备需要刷新。仅对缓存键进行索引查找会非常快。

【讨论】:

  • 太棒了,是的,我只是在想,唯一的事情是无论如何我都必须从 mongodb 中获取数据,因为我只将用户 ID 的行存储在表中(因为它也需要存储每个用户缩略图和信息的空间)
  • 所以我在想也许只是发送缓存无论如何都知道是否需要进行刷新。
  • 如果我实际上是在记录用户所做操作的更改...我不需要缓存键,因为可以假设我拥有最新数据,因为无论如何我每天都在更新它以及对数据库的主要调用
猜你喜欢
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 2017-10-16
相关资源
最近更新 更多