一种对非分区表进行分区并行读取的方法及装置
【技术领域】
本发明涉及数据处理技术领域,具体涉及一种对非分区表进行分区并行读取的方法及装置。
【背景技术】
分区表是关系数据库中普遍提供的一种将表分成若干个相对独立的分区,从而提升数据访问的性能的技术。合理使用分区表,可以解决普通表随着数据量的增加,数据的访问性能不断下降的问题。
在数据集成项目实施的过程中,当源表数据量较大时,由于抽取时间通常比较长,会导致以下问题:
1)需要长时间占用源数据库的资源,影响源数据库性能。
2)占用数据库资源过长,超过数据库允许的查询时间,导致数据库报错,数据抽取中止。
3)单次数据抽取时间过长,导致网络故障引起抽取失败的风险大大提高。
对于上述问题,传统的解决方案是:如果源表为分区表,则先查询出数据库中该表的各个分区,然后并发查询读取每个分区的数据。然而,在实际使用过程中,并非所有数据量较大的表都是分区表,一方面是因为分区表创建较为复杂,用户最开始使用时对数据量估计不足或者设计时没有考虑到,导致没有使用分区表,这种情况很普遍;另一方面是因为分区表通常使用上会有些限制,比如mysql的分区表不能有外键等导致不能使用分区表。如果数据库中的源表为非分区表,则无法解决上述问题。
鉴于此,克服上述现有技术所存在的缺陷是本技术领域亟待解决的问题。
【发明内容】
本发明需要解决的技术问题是:
在数据集成过程中,当源表数据量较大时,抽取时间通常比较长,会导致数据抽取性能下降、报错、网络故障等问题,如果源表为分区表,可实现分区并行读取,但并非所有数据量较大的表都是分区表,如果源表为非分区表,不能实现分区并行读取,则无法解决上述问题。
本发明通过如下技术方案达到上述目的:
第一方面,本发明提供了一种对非分区表进行分区并行读取的方法,包括:
对数据库中的非分区表进行分区定义;
基于所述分区定义对非分区表进行分区,得到对应的多个分区;
根据每个分区的属性动态生成分区查询语句,并将多个分区分配给多个工作线程读取。
优选的,所述对数据库中的非分区表进行分区定义具体为:
在数据集成工具内,根据非分区表的数据特征从数据库中选择合适的分区列,使得非分区表中的数据能够均匀分布到各个分区;
判断选择的各分区列的类型,并根据分区列类型确定需要定义的分区类型;
用户根据需要定义的分区类型给出所需的相关参数,完成相应的分区定义。
优选的,在进行分区定义时,支持的分区列类型包括数值型、日期时间型以及字符型,支持的分区类型包括范围分区和枚举分区;
当分区列类型为数值型或者日期时间型时,使用范围分区;当分区列为字符型时,使用枚举分区;
当定义范围分区时,用户给出的相关参数包括:分区列名称、分区列的最小值估计值、最大值估计值以及希望的分区数;当定义枚举分区时,用户给出的相关参数包括:分区列名称和每个可能的枚举值。
优选的,所述基于所述分区定义对非分区表进行分区,得到对应的多个分区,具体包括:
读取所述分区定义,并根据所述分区定义判断分区类型;
对不同的分区类型,分别采用不同的方法计算分区范围;
根据计算的分区范围,得到对应的多个分区。
优选的,对于范围分区,计算分区范围的过程具体为:
判断分区列类型,如果分区列类型为日期时间型则转换为数值型;
根据用户给出的希望的分区数,确定最终分区数量;
根据用户给出的分区列的最大值估计值、最小值估计值及确定的最终分区数量,计算每个分区的分区列的起始值和结束值。
优选的,所述根据用户给出的希望的分区数,确定最终分区数量具体为:
在用户给出的希望的分区数基础上加2,作为最终分区数量;其中,额外增加的2个分区分别为:一个包含最小可能值的分区和一个包含最大可能值的分区。
优选的,对于枚举分区,计算分区范围的过程具体为:
根据用户给出的每个可能的枚举值,确定每个分区的分区列的枚举值;其中,每个枚举值为一个分区,最终分区数量等于枚举值的个数。
优选的,所述根据每个分区的属性动态生成分区查询语句,并将多个分区分配给多个工作线程读取,具体包括:
将得到的多个分区平均分配给线程池中的多个工作线程执行;
各工作线程根据分配的分区的属性,动态生成分区SQL查询语句;
各工作线程执行对应的SQL查询,并输出查询结果。
优选的,在所述对数据库中的非分区表进行分区定义之前,所述方法还包括:
当在数据库中查询的源表为非分区表时,计算对应非分区表的数据量,并将所述数据量与预设阈值进行比较;
其中,当所述数据量大于所述预设阈值时,对该非分区表进行分区定义;当所述数据量小于等于所述预设阈值时,直接对该非分区表进行数据查询读取。
第二方面,本发明还提供了一种对非分区表进行分区并行读取的系统,完成第一方面所述的对非分区表进行分区并行读取的方法,包括依次连接设置的分区定义模块、元数据存储模块和分区查询模块;
所述分区定义模块用于在数据集成工具内部为非分区表进行分区定义,并将分区定义发送到所述元数据存储模块;
所述元数据存储模块用于接收所述分区定义模块发送来的分区定义信息,并将分区定义信息存储到文件或者数据库中;
所述分区查询模块用于从所述元数据存储模块中读取分区定义,根据分区定义计算分区范围,进而根据每个分区动态生成分区查询语句,并将分区分配给多个工作线程读取。
优选的,所述分区查询模块内设有线程池和SQL语句生成模块;
所述线程池内包括多个工作线程,以便所述分区查询模块将计算得到的各分区平均分配给所述线程池中的多个工作线程执行;
所述SQL语句生成模块用于各工作线程根据分配的分区动态生成分区SQL查询语句,以便工作线程执行SQL查询并输出查询结果。
第三方面,本发明还提供了一种对非分区表进行分区并行读取的装置,包括至少一个处理器和存储器,所述至少一个处理器和存储器之间通过数据总线连接,所述存储器存储有可被所述至少一个处理器执行的指令,所述指令在被所述处理器执行后,用于完成第一方面所述的对非分区表进行分区并行读取的方法。
与现有技术相比,本发明的有益效果是:
本发明通过为非分区表进行分区定义来模拟关系数据库中的表分区,并根据每个模拟的分区动态生成该分区查询语句,然后将分区平均分配给多个工作线程读取,从而实现了对非分区表的分区并行读取,提高数据抽取性能,减少了抽取时间以及数据库或者数据抽取工具报错的概率。同时,在定义范围分区时无需用户给出每个分区的精确范围,只需给出分区列的最大值和最小值的估计值即可,从而大大简化了分区的定义。
【附图说明】
为了更清楚地说明本发明实施例的技术方案,下面将对本发明实施例中所需要使用的附图作简单地介绍。显而易见地,下面所描述的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1为本发明实施例提供的一种对非分区表进行分区并行读取的方法流程图;
图2为本发明实施例提供的一种对非分区表进行分区并行读取的系统组成图;
图3为本发明实施例提供的一种对非分区表定义分区的方法流程图;
图4为本发明实施例提供的一种分区查询模块的运行流程图;
图5为本发明实施例提供的一种范围分区的分区范围计算流程图;
图6为本发明实施例提供的一种对非分区表进行分区并行读取的装置的架构图。
【具体实施方式】
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。下面就参考附图和实施例结合来详细说明本发明。
实施例1:
本发明实施例提供了一种对非分区表进行分区并行读取的方法,可实现对非分区表的分区并行读取。如图1所示,所述方法具体包括以下步骤:
步骤10,对数据库中的非分区表进行分区定义。
在进行分区定义时,用户可以根据需要定义分区,不必受数据库的限制,支持大多数常见的列类型作为分区列,包括数值型、日期时间型以及字符型;支持的分区类型包括范围分区和枚举分区两种。当分区列为数值型或者日期时间型时,可以使用范围分区;当分区列为字符型时,可以使用枚举分区。对于不同的分区类型,进行分区定义的方法也不同,后续将详细展开介绍,在此不再赘述。
步骤20,基于所述分区定义对非分区表进行分区,得到对应的多个分区。
根据分区定义可针对非分区表计算每个分区的分区范围,从而完成对非区分表的分区。如此一来,便可模拟数据库中的分区表,为后续实现源表数据的并行读取奠定基础。其中,对于不同的分区类型,相应计算分区范围的方法也不同,后续将详细展开介绍,在此不再赘述。
步骤30,根据每个分区的属性动态生成分区查询语句,并将多个分区分配给多个工作线程读取。
分区完成后,将得到的多个分区平均分配给线程池中的多个工作线程执行;然后各工作线程可根据分配的分区的属性,动态生成分区SQL查询语句,以便各工作线程执行对应的SQL查询,并输出查询结果。至此,实现了对数据库中非分区表的分区并行读取过程。
本发明通过为非分区表进行分区定义来模拟关系数据库中的表分区,并根据每个模拟的分区动态生成该分区查询语句,然后将分区平均分配给多个工作线程读取,从而实现了对非分区表的分区并行读取,提高数据抽取性能,减少了抽取时间以及数据库或者数据抽取工具报错的概率。
结合背景介绍可知,对于源表中的非分区表,如果数据量较大,则由于抽取时间通常比较长,若不进行分区并行读取,则容易产生数据抽取性能下降等一系列问题;但对于数据量较小的非分区表,并不会存在这样的问题。如此一来,如果在进行数据抽取时对数据库中的每个非分区表都进行分区,而没有针对性操作的话,这在一定程度上也会造成时间和资源的浪费。鉴于上述考虑,在所述对数据库中的非分区表进行分区定义之前,即步骤10之前,所述方法还包括:
当在数据库中查询的源表为非分区表时,计算对应非分区表的数据量,并将所述数据量与预设阈值进行比较;其中,当所述数据量大于所述预设阈值时,对该非分区表进行分区定义,即执行步骤10;当所述数据量小于等于所述预设阈值时,直接对该非分区表进行数据查询读取,无需执行步骤10。通过上述步骤,可仅选择数据量较大的非分区表进行分区,对于数据量较小的非分区表则无需分区,从而更有针对性地执行分区操作,提高数据抽取效率,减少资源浪费和时间浪费。其中,所述预设阈值可根据实际操作时的数据抽取性能而确定,在此不做具体限定。
在本发明实施例中,具体实施该方法时可采用图2所示的系统(数据集成工具)来完成,所述系统包含三大部分:分区定义模块、元数据存储模块和分区查询模块。在使用时,所述分区定义模块提供为非分区表定义分区的用户界面,完成分区定义后将分区定义发送到所述元数据存储模块;然后所述元数据存储模块接收所述分区定义模块发送来的分区定义信息,并将分区定义信息存储到文件或者数据库中;最后所述分区查询模块从所述元数据存储模块中读取分区定义,计算分区范围,进而根据每个分区动态生成分区查询语句,并将分区分配给多个工作线程读取。
进一步结合图3,所述对数据库中的非分区表进行分区定义,即所述步骤10(也是分区定义模块的运行过程),具体又包括以下步骤:
首先,在数据集成工具内,根据非分区表的数据特征从数据库中选择合适的分区列,使得非分区表中的数据能够均匀分布到各个分区。其中,分区列对于数据库来说是固定的,对于数据集成工具模拟是随时可以修改的,此处分区列的选择通常可由用户在数据集成工具内部完成;分区列一般要求重复的数据比较少,使得分布比较均匀,这样保证每个分区的记录数不会差别过大。
其次,判断选择的各分区列的类型,并根据分区列类型确定需要定义的分区类型。其中,当分区列类型为数值型或者日期时间型时,适合使用范围分区;当分区列为字符型时,例如地区列,则适合使用枚举分区。
最后,用户根据需要定义的分区类型给出所需的相关参数,完成相应的分区定义。其中,当定义范围分区时,用户给出的相关参数包括:分区列名称、分区列的最小值估计值、最大值估计值以及希望的分区数;当定义枚举分区时,用户给出的相关参数包括:分区列名称和每个可能的枚举值,不同枚举值为逗号分隔的字符串,如(a,b,c)表示分区列的值可能为a、b或者c。
进一步结合图4,所述基于所述分区定义对非分区表进行分区,得到对应的多个分区,即所述步骤20(也是分区查询模块的前期运行过程),具体又包括:
首先,读取所述分区定义,并根据所述分区定义判断分区类型。结合图2,所述分区查询模块从所述元数据存储模块中读取分区定义,进而可判断出分区类型是范围分区还是枚举分区。
然后,对不同的分区类型分别采用不同的方法计算分区范围,得到对应的多个分区。如果是范围分区,则计算分区范围时需计算每个分区的分区列的起始值和结束值,具体计算过程参考图5,将在后续介绍;如果是枚举分区,则只要确定根据用户给出的每个可能的枚举值,确定每个分区的分区列的枚举值即可,无需专门计算分区范围,每个枚举值即为一个分区,最终分区数量等于枚举值的个数。
继续参考图4,所述根据每个分区的属性动态生成分区查询语句,并将多个分区分配给多个工作线程读取,即所述步骤30(也是分区查询模块的后期运行过程),具体又包括:
首先,分配分区;即,计算完分区范围后,将得到的多个分区平均分配给线程池中的多个工作线程执行。然后,各工作线程根据分配的分区的属性,动态生成分区SQL查询语句;最后,各工作线程执行对应的SQL查询,并输出查询结果。因此,图4的工作流程也可认为是所述分区查询模块的整个运行过程。
其中,对于范围分区,计算分区范围的过程可参考图5,具体为:
第一,判断分区列类型,如果分区列类型为日期时间型则转换为数值型。对于范围分区,分区列的类型只能是数值型或者日期时间型。这里为了统一和简化算法,将分区列类型进行转换统一,具体为:如果分区列类型为日期时间型,则将其转换为距离格林尼治标准时间1970年1月1日0时0分0秒的毫秒数,类型为64位长整数;如果分区列类型为数值型,则无需转换;如此一来,可将分区列类型统一为数值型。
第二,根据用户给出的希望的分区数N’,确定最终分区数量N。其中,确定最终分区数量N的方法具体为:在用户给出的希望的分区数基础上加2,作为最终分区数量,即N=N’+2;额外增加的2个分区分别为:一个包含最小可能值的分区和一个包含最大可能值的分区。这是由于用户给出的分区列最大值和最小值均为估计值,而非精确数值;为了保证数据完整性,防止丢失数据,需增加一个包含最小可能值的分区和一个包含最大可能值的分区,因此最终分区数量为用户给出的分区数加2。
第三,根据用户给出的分区列的最大值估计值MAX、最小值估计值MIN及确定的最终分区数量N,计算每个分区的分区列的起始值和结束值,进而确定每个分区的范围。其中,对于用户指定的N’个分区,每个分区的正常宽度应为(MAX-MIN)/N’。
下面将通过具体的实施例来举例说明范围分区以及枚举分区的分区范围计算过程:
对于范围分区,假设分区列定义中的分区列最小值估计值为-500000,最大值估计值为500000,用户指定的分区个数为10,则10个正常分区的宽度应为(500000-(-500000))/10。但是,由于用户给出的分区列最大值和最小值均为估计值,为了保证数据完整性,本发明实施例中还需增加一个包含最小可能值的分区和一个包含最大可能值的分区,即最终分区数量为12。因此,最终分区结果如下表所示:
分区序号 |
分区范围 |
1 |
[-9223372036854775808,-500000) |
2 |
[-500000,-400000) |
3 |
[-400000,-300000) |
4 |
[-300000,-200000) |
5 |
[-200000,-100000) |
6 |
[-100000,0) |
7 |
[0,100000) |
8 |
[100000,-400000) |
9 |
[200000,-400000) |
10 |
[300000,-400000) |
11 |
[400000,-500000) |
12 |
[500000,9223372036854775807) |
其中,-9223372036854775808是64位计算机中整数的最小值,9223372036854775807是64位计算机中整数的最大值,计算机中实际数值一般不会超出这两个值之间的范围。[a,b)表示分区列的值大于等于a且小于b。假设被查询的表名称为table1,分区列为c1,则对于分区[a,b)生成的查询语句为:
select*fromtable1where c1>=a and c1<b
对于枚举分区,假设表名称为table1,分区列为c1,枚举值为(a,b,c),则分区个数3,每个分区生成的查询语句分别如下:
select*fromtable1where c1='a'
select*fromtable1where c1='b'
select*fromtable1where c1='c'
其中,在数据库中实际定义范围分区时,必须在创建表时给出每个分区的精确范围,因为数据库中的分区定义需要处理记录插入的情况,每条新记录进来时必须确定它是属于哪个分区,所以在数据库中定义分区时用户必须给出每个分区的定义;由于数据库中的分区一旦定义好了就很难调整,用户需要在创建表时对未来的数据量和范围有比较好的估计,然后给出每个分区的范围,这是目前数据库建表语句的要求。对于数据量很大的非分区表,如果需要用户给出精确的分区范围,对用户而言存在以下三个困难:一是如果分区数过多,则需要输入每个分区的最大值和最小值,工作量可能很大;二是要查询表中实际存在的最大和最小值,对于大表这个操作可能会非常耗时;三是即使要求用户输入精确的最大和最小值,但随着表中的数据不断变化,也不可能随时要求用户去修改分区定义。
在本发明实施例中,分区定义是在数据集成工具内部模拟完成,对于数据集成工具来说,只需要读取已有的数据,只要保证数据不丢失即可,则分区的范围可以计算得到,不影响数据插入。因此,定义范围分区时只要求用户输入最大和最小值的估计值即可,具体精确的分区范围由程序在运行时自动计算得到,大大减少了分区定义的工作量和难度。
综上所述,本发明实施例提供的对非分区表进行分区并行读取的方法,具有以下优势:
通过在数据集成工具内部为非分区表进行分区定义来模拟关系数据库中的表分区,并根据每个模拟的分区动态生成该分区查询语句,然后将分区平均分配给多个工作线程读取,从而实现了对非分区表的分区并行读取,提高数据读取性能和数据访问性能;
在定义范围分区时,无需用户给出每个分区的精确范围,只需给出分区列的最大值估计值和最小值估计值即可,系统可自动生成每个分区的起始值,从而大大简化了分区的定义;
在对范围分区计算分区范围时,先将日期时间类型转换为数值型,可简化和统一分区计算的算法和程序。
实施例2:
在上述实施例1的基础上,本发明实施例提供了一种对非分区表进行分区并行读取的系统(数据集成工具),可用于实现实施例1所述的对非分区表进行分区并行读取的方法,从而实现对非分区表的分区并行读取。如图2所示,本发明实施例提供的系统包括依次连接设置的分区定义模块、元数据存储模块和分区查询模块。
所述分区定义模块提供为非分区表定义分区的用户界面,具体用于在数据集成工具内部为非分区表进行分区定义,并将分区定义发送到所述元数据存储模块。其中,所述分区定义模块支持大多数常见的列类型作为分区列,如数值型、日期时间以及字符型;支持的分区类型包括范围分区和枚举分区两种。当分区列为数值型或者日期时间型时,可以使用范围分区或者枚举分区;当分区列为字符型时,可以使用枚举分区。所述分区定义模块的具体执行过程可参考图3以及实施例1中的相关介绍,在此不再赘述。
所述元数据存储模块用于接收所述分区定义模块发送来的分区定义信息,并将分区定义信息存储到文件或者数据库中。
所述分区查询模块用于从所述元数据存储模块中读取分区定义,根据分区定义对数据源提供的非分区表计算分区范围,进而根据每个分区动态生成分区查询语句,并将分区分配给多个工作线程读取,具体为:读取分区定义后判断分区类型,并根据分区类型计算分区范围;将计算得到的各分区平均分配给线程池中的多个工作线程执行;各工作线程根据分配的分区动态生成分区SQL查询语句,以便各工作线程执行SQL查询并输出查询结果。所述分区查询模块的具体执行过程可参考图4以及实施例1中的相关介绍,在此不再赘述。
进一步结合图2,所述分区查询模块内设有线程池和SQL语句生成模块。所述线程池内包括多个工作线程,以便所述分区查询模块将计算得到的多个分区平均分配给所述线程池中的多个工作线程执行;所述SQL语句生成模块用于各工作线程根据分配的分区动态生成分区SQL查询语句,以便工作线程执行SQL查询并输出查询结果。
其中,所述分区查询模块在计算分区范围时,如果是范围分区,则需根据用户提前给出的分区列的最小值估计值、最大值估计值以及希望的分区数,计算每个分区的分区列的起始值和结束值;如果是枚举分区,则需根据用户提前给出的所有枚举值,确定每个分区的分区列的枚举值即可,无需专门计算分区范围。这是因为,对于枚举分区,每个枚举值即为一个分区,最终分区数量等于枚举值的个数。
综上所述,本发明实施例提供的对非分区表进行分区并行读取的系统,具有以下优势:
通过分区定义模块在数据集成工具内部为非分区表进行分区定义来模拟关系数据库中的表分区,并由分区查询模块根据每个模拟的分区动态生成该分区查询语句,然后将分区平均分配给多个工作线程读取,从而实现了对非分区表的分区并行读取,提高数据读取性能和数据访问性能;
所述分区查询模块在计算范围分区时,无需用户给出每个分区的精确范围,只需给出分区列的最大值估计值和最小值估计值即可,系统可自动生成每个分区的起始值,从而大大简化了分区的定义;同时,在对范围分区计算分区范围时,先将日期时间类型转换为数值型,可简化和统一分区计算的算法和程序。
实施例3:
在上述实施例1提供的对非分区表进行分区并行读取的方法的基础上,本发明还提供了一种可用于实现上述方法的对非分区表进行分区并行读取的装置,如图6所示,是本发明实施例的装置架构示意图。本实施例的对非分区表进行分区并行读取的装置包括一个或多个处理器21以及存储器22。其中,图6中以一个处理器21为例。
所述处理器21和所述存储器22可以通过总线或者其他方式连接,图6中以通过总线连接为例。
所述存储器22作为一种对非分区表进行分区并行读取的方法非易失性计算机可读存储介质,可用于存储非易失性软件程序、非易失性计算机可执行程序以及模块,如实施例1中的对非分区表进行分区并行读取的方法。所述处理器21通过运行存储在所述存储器22中的非易失性软件程序、指令以及模块,从而执行对非分区表进行分区并行读取的装置的各种功能应用以及数据处理,即实现实施例1的对非分区表进行分区并行读取的方法。
所述存储器22可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他非易失性固态存储器件。在一些实施例中,所述存储器22可选包括相对于所述处理器21远程设置的存储器,这些远程存储器可以通过网络连接至所述处理器21。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。
所述程序指令/模块存储在所述存储器22中,当被所述一个或者多个处理器21执行时,执行上述实施例1中的对非分区表进行分区并行读取的方法,例如,执行以上描述的图1、图3-图5所示的各个步骤。
本领域普通技术人员可以理解实施例的各种方法中的全部或部分步骤是可以通过程序来指令相关的硬件来完成,该程序可以存储于一计算机可读存储介质中,存储介质可以包括:只读存储器(ROM,Read Only Memory)、随机存取存储器(RAM,Random AccessMemory)、磁盘或光盘等。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。