最近写了一个分表查询的lib,封装了一些数据结构,可以简化对于分表查询的实现。这个问题主要体现在,对分表进行查询时,原有的单表查询需要进行修改,或者需要在内存中进行处理。修改单表的sql可能导致性能问题,原有的优化可能失效。内存处理则需要一些技巧,搞不好会把太多内容加载到内存中,导致内存被耗光。
我的lib主要使用iterator的模式来解决数据库的读取的问题,每次只读取1000条,放在内存中,当iterator的next移动到缓冲区的尾部时,再次读取1000条,如此可以保证获得所有的数据。当然我们也可以采用双buffer的方式,一个用于提前读取,一个用于输出。不过现在还没这么做。
虽然command模式不是lib的重点,但是这个模式却教会了我一些东西。因为最开始的时候,我并没有想到它。开始,我想的是查询分成几类:
1. 查询结果做union all;
2.查询结果做order by
3. 查询结果做group by
4. 查询结果去重
我发现每个查询都有这样一些参数,一组表名,一个数据库查询的封装,如果需要排序的话,得要一个comparator,如果需要合并的话,得要一个MapReduce。
最初的实现是:
|
后来发现参数太多,初始化比较麻烦,于是改成:
|
接着发现,这个设计缺乏扩展性,如果将来需要添加新的查询类型,或者想要换一种实现方式,就得修改整个query service。而且X X1 X2只有属性,太浪费了,没有实现封装的目的。更重要的,各个查询其实如果设置好上下文,调用方法都一样,返回值一样。这不就是command的用法吗。
|
这样上面的难题就迎刃而解了。为什么我一开始没想到呢。我想到了不同的种类的查询,过分关注他们的不同点,忽略了查询的共同点。所以以后工作中,一定要先抽取共性,再寻求个性。共性有利于整体考虑,个性有利于细化架构,发现新的机会。