如何在数学上做“GROUP BY”?

时间:2012-04-02 04:39:23

标签: sql database group-by grouping key-value

我有一个键值对的数据结构,我想实现“GROUP BY”值。 键和值都是字符串。

所以我所做的就是给每个值(字符串)一个唯一的“素数”。然后,对于每个键,我存储了与特定键具有的不同值相关联的所有素数的乘法。 因此,如果关键字“Anirudh”具有值“x”,“y”,“z”,那么我也存储数字M(Key)= 2 * 3 * 5 = 30。 稍后,如果我想按特定值“x”(例如)进行分组,那么我只是迭代所有键,并将M(键)除以与“x”相关联的素数。然后我检查余数是否为0,如果它是零,则该特定“密钥”是值为“x”的分组的一部分。

我知道这是最奇怪的方式。有些人对键值对进行排序(按值排序)。我本可以创建另一个已经按“值”分组的表(哈希表)。所以我想知道比我更好的方法(必须有很多)。在我的方法中,随着特定键的唯一值的数量增加,素数的乘积也增加(这也是指数地)。

2 个答案:

答案 0 :(得分:1)

如果没有真正的想法在这里被问到什么,但这听起来类似(但计算上更昂贵)比位向量或2的幂之和。第一个值是“1”,第二个是“2”,第三是“4”,依此类推。如果你得到“7”,你知道它是“第一”+“第二”+“第三”。

答案 1 :(得分:1)

您的方法将始终执行O(n)来查找组成员,因为您必须遍历集合的所有元素才能找到属于目标组的元素。如果您有许多元素,那么您的方法还存在溢出公共整数边界(32,64位)的风险,因为您可能会将大量素数相乘以形成您的密钥。

使用位掩码跟踪此方法后的组成员资格,您会发现它更有效,更可预测。如果您有16个组,则可以使用位掩码表示16位短。按照你的建议使用素数,你需要一个有足够位的整数来保存数字32589158477190044730(前16个素数相乘),这需要65位。

分组的其他方法也是第一次迭代的O(n)(毕竟,每个元素必须至少测试一次以获得组成员资格)。但是,如果您倾向于重复相同的组检查,那么您引用的其他方法(例如,为每个目标组保留列表或哈希表)会更有效,因为后续的组成员身份测试是O(1)。

所以直接回答你的问题:

  • 如果群组成员资格有多个查询(重复某些群组),那么存储群组的任何解决方案(包括您在问题中建议的解决方案)都会比您的方法效果更好。
  • 如果没有重复查询群组成员资格,则存储群组成员资格没有优势

鉴于重复查询似乎可能基于您的问题:

  • 如果您希望换取内存以获得更快的速度,请使用键入组ID的列表等结构来存储组成员资格。
  • 如果您想交换速度以减少内存使用,请使用适当宽位数组来存储组成员资格。