我有一个2000万人的数据集,其位置是众所周知的。在接近实时的情况下,我想知道我收到的查询是否在此集合中,如果是,则是实际位置。基本上,我想要一个大型哈希表。由于卷(每秒数千个查询),为Redis / Memcached支付网络往返是不可能的。
是否有可以提供非常快速的成员资格测试和数据检索的数据结构?可以接受少量错误。
有些地方比其他地方更受欢迎。例如,“美国,纽约,纽约”的出现频率远高于“美国,阿拉斯加,安克雷奇”。
答案 0 :(得分:1)
“2000万” - “我想要一个大型哈希表” - 听起来你已经有了答案。包含2000万个项目的哈希映射很容易适合单个进程在单个机器上使用的内存。
std::unordered_map<Key, Value>
System.Collections.Generic.Dictionary<Key, Value>
java.util.HashMap<Key, Value>
HashMap[Key, Value]
如果您告诉我们您使用的语言,我们可以为您指出该语言的确切类型。
此外 - 尽管我认为这可能有点过分 - 你可以使用辅助Bloom filter(猖獗的想法 - 不是我的 - 只是为了完整而将其包括在内)以便在给定人员的情况下加速成员资格测试(键)在哈希映射中不。
答案 1 :(得分:1)
您可以使用Bloomier filter:
布隆过滤器 [...] 是一种节省空间的概率数据结构,用于测试元素是否是集合的成员。假阳性检索结果是可能的,但假阴性不是;即查询返回&#34;内部集合(可能是错误的)&#34;或者&#34;绝对不在集合中#34;。元素可以添加到集合中,但不会被删除(尽管可以通过计数过滤器来解决)。添加到集合中的元素越多,误报的可能性就越大。
<强> [...] 强>
Chazelle等人。 (2004)设计了Bloom过滤器的泛化,它可以将值与已插入的每个元素相关联,从而实现关联数组。与布隆过滤器一样,这些结构通过接受小的假阳性概率来实现小的空间开销。在&#34; Bloomier过滤器&#34;的情况下,误报被定义为当键不在地图中时返回结果。地图永远不会为地图中的键返回错误的值。
答案 2 :(得分:0)
一种选择是使用简单明了的地图:
// Scala
val locations: Map[String, Geo] = Map.empty
def location(id: String): Option[Geo] = locations.get(id)
但这会耗费大量内存。
答案 3 :(得分:0)
答案 4 :(得分:0)
使用排序数组并进行二进制搜索是另一种选择:
val ids: Array[Long] = new Array(30000000)
val values: Array[Int] = new Array(30000000)
var lookups = Map.empty[String, Int]
// populate ids with sorted array read from disk
Source.fromFile("sorted.csv").map(_.split("\t")).zipWithIndex.foreach {
case (Array(id, value), index) =>
ids[index] = id.toLong
values[index] = lookups.get(value) match {
case Some(valueIndex) => valueIndex
case None =>
val valueIndex = values.size + 1
lookups = lookups.updated(value, valueIndex)
valueIndex
}
}
// Flip lookups around: value becomes key, key becomes value
val realLookup = lookups.foldLeft(Map.empty[Int, String]) {
case (memo, (value, index)) => memo.updated(index, value)
}
// Usage:
Source.fromFile("ids.csv").foreach {
idStr =>
val id = idStr.toLong
val index = java.util.Arrays.binarySearch(ids, id)
if (index < 0) {
// Unknown -- check javadoc
println(idStr)
} else {
// Known
println(id + "\t" + realLookup(values(index))
}
}