我有一个15整数列,表中有5,000,000行。给定包含15个整数的输入记录,我需要将输入记录与5,000,000记录表进行比较,并获得所有匹配的行。
注1:一行中的所有整数都是唯一的 注2:匹配列的顺序和输入记录并不重要 例如:1,10,15,23,9,22,99,11,19,32,45,21,76,12,33和33,10,15,99,11,19,32,45,21 ,23,9,22,76,12,1应该产生匹配结果
是否可以实现散列函数/按位运算来为每一行生成唯一索引。如果记录中的值相同,该函数可以返回2行的相同索引
答案 0 :(得分:2)
这并不多,但应该让你开始。
你可能想要一个产生尽可能少的冲突的哈希函数;但它也必须是可交换的(即:你在哈希中添加数字的顺序是无关紧要的)。您可以通过结合使用XOR和位移来实现这一目标(请参阅此page)。
您可能希望将哈希存储在另一列中。然后,您可以对要查找的输入进行哈希处理,并在数据库中查找哈希值。请注意,哈希允许误报,因此您仍然需要检查候选行是否实际上是您想要的(即:对所有内容进行排序并进行比较)。
答案 1 :(得分:1)
正确完成工作并对每行中的整数进行排序并对表中的行进行排序。在使用表的整个生命周期中,排序成本将低于您倾向于的所有散列和散乱。当你在它时,在表中建立一个索引,可能来自每行的前2或3个整数。
答案 2 :(得分:0)
对于快速查询,您可以预处理表。我将创建一个HashMap,其中15个值的排序数组是键,并且列索引的列表,其中排序结果到相同的数组是值。例如,条目可能如下所示:
[1,9,10,11,12,15,19,21,22,23,32,33,45,76,99] => [12, 33]
因此15个值位于第12列和第33行。
对于密钥,您必须创建自定义散列并等于函数。
hash *= 120941 + x
。参见例如here用于更好的哈希函数。答案 3 :(得分:0)
正如“高绩效标志”所暗示的那样(我身边+1) - 的确,这是正确的做法。您应该对行进行排序(以便按排序顺序将15个整数放在列中)。这样,在比较两行时,您可以轻松找到它们是否相同(从任何一端开始,直到找到不匹配为止 - 如果您所有15个数字匹配则匹配)。
如果你只需要一个哈希函数来建立索引,那么同样的想法可以帮助你: 对15行中的数字进行排序,并创建一个等于:
的哈希值i = 1到15的总和(a_i * k ^ i)// k是一个正整数 - 见下文
这给你一个相当不错的索引。如果你可以保持k非常大,这可以证明是无冲突的,但索引值的大小会增加。即使k为2,对于500万行和15列也很大程度上是无冲突的,假设整数范围是2 ^ 16。
另一个想法 - 既然你主要关注启发式,你也可以考虑一种更简单的方法:
保留3个列,分别为最小值,最大值和15列的总和。检查这3个匹配2行是否会消除大量的真阴性。一些误报仍将存在。 (很容易注意到,在上面的方案中使用k = 1与保持列的总和作为索引值相同,这是该子解决方案中提到的3个值之一。)
[一个可能是禁区的问题 - 您的数据库设计是否灵活?这似乎不是一个稳定的设计,因为列似乎代表子实体,但我没有详细说明能够最终确定。]