我有一个应用程序(针对特定的推特用户)获取您关注的推特用户列表但不关注您。它这样做:
我想出的一个简单的方法就是拥有许多与用户有关系的人和不跟你回来的人,例如:
User table
-id
TwitterUser table
-user_id
-timestamp
-isFollowing
因此,对于给定用户,我可以获得所有非跟随用户的SQL模式,并且可以通过时间戳来比较它们以匹配上述要求。
但是,我希望有一个更好的数据库后端代表这个数据集而不是一个sql数据库。我一直在尝试使用redis,但不确定如何将它拉下来。
我想也许是文档存储 - b / c我想做的就是获取两个数据集的差异。或者更准确地说:我想区分两个推特用户ID列表。
有什么想法吗?
答案 0 :(得分:5)
比较两个阵列的Bruteforce方法将具有O(N * M)的时间复杂度,其中N和M是阵列的大小。因此,我们应该使用一些智能数据结构来存储它们,以便有效地实现这一目标。
我想出了以下方法:
twitter ids列表是一个集合,因为ID是唯一的。 Redis支持
设置并允许执行差异等集合操作。假设
您有2套密钥ids_at_time_x
和ids_at_time_y
。
使用SADD
向他们添加元素
像这样:
SADD ids_at_time_x "15424"
当您准备执行差异执行
时SDIFF ids_at_time_x ids_at_time_y
这将返回来自ids_at_time_x
的非ID列表
出现在ids_at_time_y
。如果要进行反向操作,
即检索ids_at_time_x
中不存在的ID列表,
只是交换参数:
SDIFF ids_at_time_y ids_at_time_x
关于SDIFF的最好的事情是它非常有效地运作 - 时间复杂度为O(N),其中N是元素的总数 这2套。即使您进行2次差异操作,时间复杂度也会增加 仍然是线性的。
将它们存储为已排序的列表。 Redis支持有序集。添加时 你必须包含一个元素分数(Redis将根据分数进行排序),这等于你的id 情况下:
ZADD ids_at_time_x 15424 "15424"
当列表准备就绪时,我们检索它们并将它们进行比较 码。这是伪代码:
n = size of A
m = size of B
i = 0
j = 0
setA = [] // List of elements that present only in A
setB = [] // List of elements that present only in B
intersection = [] // List of elements that present in A and B
while i < n or j < m {
if j == m {
setA.add(A[i])
i = i + 1
} else if i == n {
setB.add(B[j])
j = j + 1
} else if A[i] < B[j] {
setA.add(A[i])
i = i + 1
} else if B[j] < A[i] {
setB.add(B[j])
j = j + 1
} else {
intersection.add(A[i])
i = i + 1
j = j + 1
}
}
说明:我们使用A和B排序的事实。我们有两个索引,都从零开始。比较 A和B的两个第一个元素。如果A [0]小于B [0],我们知道 A [0]仅存在于A中,因此我们将其添加到列表setA和 将A的指数增加一。如果B [0]小于A [0],我们加B [0] 到列表setB并将B的索引增加1。如果A [0] == B [0]我们 将A [0]添加到交叉点列表并增加两个索引。 该代码也适用于线性时间O(N),其中N是总数 A和B中的元素。
请注意,此方法适用于任何可以返回排序列表的数据库,这意味着您可以将其存储在传统的SQL数据库中并使用ORDER BY twitter_id
检索列表。
查看Redis支持的所有Data types及其命令的完整列表,它们都有很好的文档记录。 Redis还有许多语言的官方客户,所以这应该不是问题。 您仍然可以将重要数据存储在SQL数据库中,并让Redis处理ID列表。
答案 1 :(得分:0)
neo4j(http://neo4j.org)是一个数据库引擎,用于将数据存储为图形。我没有任何实际使用neo4j的经验,但看起来它很适合。