Closed juniaoshaonian closed 1 year ago
但这个有个问题分组键可能是不同数据类型的,我们如何将他们转化成key呢 这个可以考虑使用 ekit 里面的 TreeMap。然后 Key 本身被定义成一个结构体:
type Key struct { columnValues []any }
这个 Key 本身会实现 Compare 的方法,那么在 Compare 的时候就直接比较 columnValues 就可以了。也就是类似于从左到右比较每一个元素,比如说最开始是 a.columnValues[0],然后 if a.columnValues[0] > b.columnValues[0] 那么就是 a 比较大。如果全部都相等,那么就相等。
这里会有一个问题,就是代码可能比较呆,因为你在这里也不太能够用泛型。比如说 columnValues 里面的元素可能是基本类型,sql.NullXXX 类型,字节数组类型。不过这部分内容你在排序里面已经处理过一次了,实际上是可以复用的。
你需要小心设计测试用例,要覆盖不同的 GROUP BY 的列的元素类型。还要额外考虑:
仅限中文
使用场景
分组键的选择
● 分组键是shardingkey 如果是shardingkey的情况,意味着一个组的元素只会在一个sql.Rows中,逻辑和batchMerger差不多,一条一条从sqlRows里面拿数据就可以了。我们可以直接复用即可 ● 分组键不是shardingkey 不是shardingkey的情况就比较恶心一点了,意味着一个组的元素可能分布在多个sql.Rows。我们需要拿到全部数据然后根据分组键的信息拿到同一个组的信息,进行merger计算。 这种计算方式很显然如果数据量比较大会导致内存占用过多。这个问题比较难解决。用户可以自己通过控制结果集大小来控制内存大小。对这方面我们不做控制。因为我们无法得知用户的具体一行有多大数据。我们到底是1000条去进行限制还是说2000条。
分组信息的匹配
由于我们需要根据分组键的信息去找到相同组的数据,查询的时候就需要携带上分组键的信息。比如 select actorid,SUM(filmid) group by actorid。这个sql是查演员有多少部电影作品。在merger计算的时候需要通过actorid在sqlRows列表中找到相同actorid的数据。当然这个是针对分组键不是shardingkey的情况。
设计