一种数据库扩容方法和装置以及访问数据库的方法和装置
技术领域
本申请涉及数据库技术领域,特别涉及一种数据库扩容方法和装置以及访问数据库的方法和装置。
背景技术
在目前的大数据时代,一般采用数据库对海量的数据进行存储和管理。随着数据的累积,数据库中数据表的数据量也随之增大。当数据库中一张数据表的数据量过大时,数据表的读写效率会下降,甚至有可能无法进行正常的读写,此时在该数据表中一般不应再增加新的数据。例如,当数据库中一张表的数据量过大时,对该表进行查询操作所需要的时间会增加,甚至因数据量过大而使查询操作超时,最终导致查询操作无法完成。
现有技术中,当数据库中的数据量过大时,往往需要对数据库进行扩容。分表是一种常用的数据库扩容方法。分表通常是将由一个数据表存储管理的海量数据拆分为由多个数据表存储管理。当一张表的数据量过大时,一般选择分表的方法提高数据库的读写效率。例如,当数据库中一张表的数据量过大时,会采用分表的方法将该表中的数据按照某种规则分散存储到多张结构相同的表中。这样,有效地控制了单表数据量,将一张表的读写操作压力分摊到多个表上,从而提高了数据库的读写效率。
但是,上述现有技术中的数据库扩容方法,为了保证分表后旧表中存储的数据仍然可以被有效访问,通常需要将旧表中的数据迁移到多张结构相同的新表中。数据迁移的过程复杂。在数据迁移的过程中,通常需要临时关闭整个数据库的运行,从而不能提供访问,这对于在线服务要求较高的数据库并不适用。
发明内容
本申请实施例的目的是提供一种数据库扩容方法和装置以及访问数据库的方法和装置,以在数据库扩容的过程中保持数据库的访问。
为解决上述技术问题,本申请实施例提供一种数据库扩容方法和装置以及访问数据库的方法和装置是这样实现的:
一种数据库扩容方法,包括:
从数据库中选取第一数据表;
从第一数据表中选取字段,根据所述字段获取第一数据表中数据的分类数;
根据所述分类数在数据库中建立第二数据表,所述第二数据表的结构与所述第一数据表的结构相同;
保持第一数据表中的数据,当需要在数据库中写入新的数据时,将所述新的数据写入到第二数据表中。
另一种数据库扩容方法,包括:
根据数据库中每张数据表的分类规则生成分类规则数据;
从数据库中选取第一数据表;
根据所述第一数据表从分类规则数据中选取分类规则;
根据选取的分类规则得到第一数据表中数据的分类数;
根据所述分类数在所述数据库中建立第二数据表,所述第二数据表的结构与所述第一数据表的结构相同;
在建立第二数据表后,保持第一数据表中的数据,当需要在数据库中写入新的数据时,将所述新的数据写入到第二数据表中。
一种数据库扩容装置,包括:
第一选取模块,用于从数据库中选取第一数据表;
第一分类模块,用于从第一数据表中选取字段,根据所述字段获取第一数据表中数据的分类数;
建立模块,用于根据所述分类数在数据库中建立第二数据表,所述第二数据表的结构与所述第一数据表的结构相同;
保持模块,用于在建立第二数据表后,保持第一数据表中的数据,当需要在数据库中写入新的数据时,将所述新的数据写入到第二数据表中。
另一种数据库扩容装置,包括:
第一生成模块,用于根据数据库中每张数据表的分类规则生成分类规则数据;
第一选取模块,用于从数据库中选取第一数据表;
第二选取模块,用于根据所述第一数据表从分类规则数据中选取分类规则;
第二分类模块,用于根据选取的分类规则得到第一数据表中数据的分类数;
建立模块,用于根据所述分类数在数据库中建立第二数据表,所述第二数据表的结构与所述第一数据表的结构相同;
保持模块,用于在建立第二数据表后,保持第一数据表中的数据,当需要在数据库中写入新的数据时,将所述新的数据写入到第二数据表中。
一种访问数据库的方法,包括:
接收访问数据库中数据表的请求;
对访问请求进行解析,得到操作方式和第一数据;
从根据数据表开始逐层获取数据表的分类规则,分别根据各个分类规则和第一数据得到数据表,将根据各个分类规则得到的数据表作为数据表集合;
根据所述操作方式和第一数据,对数据表集合中的数据表进行操作。
一种访问数据库的装置,包括:
接收模块,用于接收访问数据库中数据表的请求;
解析模块,用于对访问请求进行解析,得到操作方式和第一数据;
计算模块,用于从根据数据表开始逐层获取数据表的分类规则,分别根据各个分类规则和第一数据得到数据表,将根据各个分类规则得到的数据表作为数据表集合;
执行模块,用于根据所述操作方式和第一数据,对数据表集合中的数据表进行操作。
由以上本申请实施例提供的技术方案可见,本申请实施例数据库的扩容方法,从数据库中选取第一数据表,并对选取的第一数据表中的数据进行分类,进而得到分类数,最后根据分类数在数据库中建立数据表。与现有技术相比,本申请实施数据库的扩容方法,在数据库中建立数据表后,不需要将第一数据表中的数据迁移到新建立的数据表中,而是保持第一数据表中的数据,避免了数据库扩容的过程中大规模的数据迁移,进而保证了在数据库扩容的过程中保持数据库的访问。
附图说明
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1为现有技术中一种分表方法;
图2为本申请实施例一种数据库扩容方法;
图3为本申请实施例另一种数据库扩容方法;
图4为本申请实施例一种数据库中数据表的分类规则;
图5为本申请实施例一种访问数据库的方法;
图6为本申请实施例另一种数据库中数据表的分类规则;
图7为本申请实施例一种数据库扩容装置;
图8为本申请实施例另一种数据库扩容装置;
图9为本申请实施例一种访问数据库的装置。
具体实施方式
为了使本技术领域的人员更好地理解本申请中的技术方案,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本申请保护的范围。
在本申请的说明书中:
数据库分表一般是将由一个数据表存储管理的海量数据拆分为由多个数据表存储管理。
字段一般指数据表中的列。在数据表中,每一列一般称为一个字段。
记录一般指数据表中的行。在数据表中,每一行一般称为一个记录。
数据表的层次指一数据表在数据库中与其它数据表之间的关系。在数据库中数据表一般呈树形结构。例如,根数据表为第0层,由根数据表派生出的数据表为第1层,由第1层数据表派生出的数据表为第2层,其它数据表的层次以此类推。
热点问题:为了保证数据表中数据的完整性,当同一时刻两个或两个以上的操作(例如增加数据、修改数据、删除数据、查询数据等)都是针对一张数据表进行时,后一个操作必须等到前一个操作执行完毕后才能进行。当一张数据表中的数据量很大时,一次操作执行的时间就较长,后一个操作的等到时间也较长,由此造成的问题一般称为热点问题。
现有技术中,一个典型的分表过程如图1所示。
在数据库1中,有4张数据表T0、T1、T2和T3。该4张数据表用于存储A、B、C、D 4个省的订单数据。其中,T0数据表用于存储A省的订单数据,T1数据表用于存储B省的订单数据,T2数据表用于存储C省的订单数据,T3数据表用于存储D省的订单数据。T0、T1、T2和T3数据表存储订单数据的上限均为1000万条,并且均包括ID字段(int)、num字段(int)和name字段(varchar)。其中,ID字段为订单数据的编号,num为订单的数量,name为订单的用户名。若某一情况下,D省的订单数据较多,T3数据表的数据量达到1000万条,T3数据表的读写效率开始下降。此时,T3数据表不再增加新的D省的订单数据。需要对T3数据表进行分表,即将D省的订单数据由T3数据表存储管理拆分为由多个数据表存储管理。
对T3数据表进行分表的过程如方框2所示,具体如下:
选取T3数据表的ID字段,按照ID除以5取余(%5)的方法对T3数据表进行分表。由于ID%5的结果有5种,因此,在数据库1中增加5张数据表T3_0、T3_1、T3_2、T3_3和T3_4。该5张数据表的结构(例如字段、字段的数据类型、索引等)与T3数据表的结构相同。为了保证分表后T3数据表中存储的数据仍然可以被有效访问,通常需要将T3数据表中的数据迁移到T3_0、T3_1、T3_2、T3_3和T3_4数据表中。
具体的迁移过程为:
依次选取T3数据表中的每一个记录;
当该记录的ID%5=0时,将该记录迁移到T3_0表中;
当该记录的ID%5=1时,将该记录迁移到T3_1表中;
当该记录的ID%5=2时,将该记录迁移到T3_2表中;
当该记录的ID%5=3时,将该记录迁移到T3_3表中;
当该记录的ID%5=4时,将该记录迁移到T3_4表中。
迁移过程完成后,删除T3数据表及其数据。形成新的数据库1’。
当数据库1’需要增加D省的订单数据时,可以将该订单数据存储在T3_0、T3_1、T3_2、T3_3或T3_4中的任一数据表中。
当数据库1’需要查询某一D省的订单数据时,需要在T3_0、T3_1、T3_2、T3_3和T3_4数据表中进行查询。
当数据库1’需要修改、删除某一D省的订单数据时,需要首先在T3_0、T3_1、T3_2、T3_3和T3_4数据表中查询到该订单数据,然后在相应的数据表中修改、删除该订单数据。
上述现有技术中的数据库扩容方法,需要对T3数据表中的数据进行迁移。
本申请实施例提供一种数据库扩容方法和装置,可以避免进行数据迁移。如图2所示,数据库扩容方法包括:
S201:从数据库中选取目标数据表。
数据库中一般有多张数据表。从所述数据库中选取的目标数据表的数量可以为1个,也可以为多个。
一般情况下,所述目标数据表为数据量较大或数据增长速度较快的数据表。
在某一实施方式中,需要获取数据库中每张数据表的数据量。然后将每张数据表的数据量与预设数据量进行比较。若数据库中某张数据表的数据量大于预设数据量,则表明该数据表的读写效率开始下降。此时,该数据表中不再增加新的数据,从而将该数据表作为目标数据表。
在另一实施方式中,需要获取数据库中每张数据表的数据量和数据增长率。所述数据增长率可以从该数据表的历史数据中计算得出,也可以根据经验预估得出。然后根据每张数据表的数据量和数据增长率,计算得出该数据表在未来一段时间内的数据量。最后将每张数据表计算得到的数据量与预设数据量进行比较。若数据库中某张表计算得到的数据量大于预设数据量,则表明该表的读写效率在未来一段时间内会下降。此时,将该数据表作为目标数据表。
所述预设数据量根据实际情况灵活设定。一般情况下需要考虑对数据库的读写速度需求和服务器的运算能力。一方面,若对数据库的读写速度要求不高,则该预设数据量可以设定的大些。若对数据库的读写速度要求较高,则该预设数据量可以设定的小些。另一方面,若服务器的运算能力较高,例如有运算能力较强的CPU和大的内存,则该预设数据量可以设定的大些。若服务器的运算能力较低,则该预设数据量可以设定的小些。
S202:从目标数据表中选取字段,根据选取的字段对目标数据表中的数据进行分类。
当所述目标数据表的数量是1个时,从该目标数据表中选取字段,根据该字段对目标数据表中的数据进行分类。
当所述目标数据表的数量是多个时,针对每一个目标数据表,从该目标数据表中选取字段,并根据该字段对该目标数据表中的数据进行分类。每个目标数据表所选取的字段可以相同,也可以不同。
在某一实施方式中,从目标数据表中选取数据类型为整型的字段(例如ID字段),按照该字段除以某数后取余的方法对数据表中的数据进行分类。
在另一实施方式中,从目标数据表中选取数据类型为字符型的字段,获取该字段字符的哈希值,按照该哈希值除以某数后取余的方法对数据表中的数据进行分类。或者,从所述哈希值中选取数位,按照选取的数位的数值对数据表中的数据进行分类。
下面以一个目标数据表为例,详细说明对该目标数据表中的数据进行分类的过程。该目标数据表的字段包括ID、账户的登录名。
一般情况下,数据表中ID字段的数据类型为整型(int),并且具有递增的属性。例如,某一状态下,ID字段的最大值为1000。此时,向该数据表中增加一个记录,则ID字段的最大值变为1001。每向该数据表中增加一个记录,ID字段的最大值加1。因此,在某一实施方式中,可以选取数据表的ID字段,按照该字段除以某数后取余的方法对数据表中的数据进行分类。
例如,按照ID除以3取余(%3)的方法数据表中的数据进行分类。由于ID%3的结果有3个,即0、1或2。因此,可以将数据表中的数据分为T_0、T_1、T_2共3类。即针对数据表中的每一记录,若该记录的ID%3的结果为0,则将该记录分入T_0类;若该记录的ID%3的结果为1,则将该记录分入T_1类;若该记录的ID%3的结果为2,则将该记录分入T_2类。
一般情况下,数据表中账户的登录名字段的数据类型为字符型(char)。因此,在另一实施方式中,可以选取数据表的账户的登录名字段,通过对数据表的账户的登录名字段取哈希值(hash)的方法对数据表中的数据进行分类。例如,对登录名字段取哈希值,以哈希值的最后一位(还可以是其它位的数值,例如倒数第二位的数值)的数值对该数据表中的数据进行分类。由于哈希值的最后一位的数值为0、1、2、3、4、5、6、7、8、或9,因此可以将数据表中的数据分为T_0、T_1、T_2、T_3、T_4、T_5、T_6、T_7、T_8、T_9共10类。即针对数据表中的每一记录,取该记录登录名字段的哈希值,若该记录登录名字段的哈希值的最后一位的数值为0,则将该记录分入T_0类;若该记录登录名字段的哈希值的最后一位的数值为1,则将该记录分入T_1类;若该记录登录名字段的哈希值的最后一位的数值为2,则将该记录分入T_2类;若该记录登录名字段的哈希值的最后一位的数值为3,则将该记录分入T_3类;若该记录登录名字段的哈希值的最后一位的数值为4,则将该记录分入T_4类;若该记录登录名字段的哈希值的最后一位的数值为5,则将该记录分入T_5类;若该记录登录名字段的哈希值的最后一位的数值为6,则将该记录分入T_6类;若该记录登录名字段的哈希值的最后一位的数值为7,则将该记录分入T_7类;若该记录登录名字段的哈希值的最后一位的数值为8,则将该记录分入T_8类;若该记录登录名字段的哈希值的最后一位的数值为9,则将该记录分入T_9类。
在另一实施方式中,也可以根据选取的字段将目标数据表中的数据分为1类,即将目标数据表中的数据作为一个整体,分入到一个类别中。
S203:根据目标数据表中数据的分类数,在所述数据库中增加数据表,增加数据表的结构与目标数据表的结构相同。
一般情况下,数据库中增加数据表的数量与目标数据表中数据的分类数相同。所述结构包括数据表中的字段、数据表的索引等。
在数据库中增加数据表后,目标数据表中的数据保持不变,但不在目标数据表中写入新的数据,而是对该目标数据表进行数据的查询、修改或删除的操作。
在数据库中增加数据表后,增加的数据表用于写入新的数据,同时,增加的数据表也可用于数据的查询、修改或删除的操作。
例如,在数据表中,按照ID字段除以某数后取余的方法将数据表中的数据分为3类,则在数据库中增加3张数据表。
又如,在数据表中,通过对账户的登录名字段取哈希值的方法将数据表中的数据分为10类,则在数据库中增加10张数据表。
又如,在数据表中,根据选取的字段将数据表中的数据分为1类,则在数据库中增加1张数据表。
由以上本实施例的技术方案可知,与现有技术相比,本实施例中的数据库扩容方法不需要将目标数据表中的数据迁移至新增加的数据表中,而是保留目标数据表中的数据。当需要在数据库中写入新的数据时,将新的数据写入到新增加的数据表中。对于目标数据表,只需要进行删除、修改、查询操作。因此,本实施例中的数据库分表方法避免了数据库扩容过程中进行大规模的数据迁移,从而避免了临时关闭数据库的运行,从而实现了对数据库的平滑扩容。
同时,本实施例中的数据库扩容方法,将数据由一个数据表存储管理拆分为由多个数据表共同存储管理,有效地控制了单表数据量,避免了同一时刻所有操作(例如,增加数据、查询数据、修改数据、删除数据)都针对一张数据表进行。本实施例中的数据库扩容方法通过将一张表的读写操作压力分摊到多个表上,从而避免了热点问题。
同时,本实施例中的数据库扩容方法,可以选取数据表的不同字段作为分表依据,例如ID字段、账户的登录名字段等。这样增加了数据库扩容的灵活性。
在本申请的另一实施例中,预先建立数据表的分类规则。当需要对数据表进行分类操作时,选取与该数据表相对应的分类规则进行分类。本实施例的数据库扩容方法,如图3所示,包括:
S301:建立数据库中每张目标数据表的分类规则,并生成分类规则数据。
建立数据库中每张目标数据表的分类规则,根据每张目标数据表的分类规则生成分类规则数据。所述分类规则数据包括每张数据表的表名和每张数据表的分类规则。
所述分类规则,一般指采用某种方法对目标数据表中的数据进行分类,根据分类数在数据库中增加数据表,增加的数据表的结构与目标数据表的结构相同。
在某些实施方式中,所述分类规则指从数据表中选取字段,根据选取的字段获对数据表中的数据进行分类。
例如,从目标数据表中选取数据类型为整型的字段(例如ID字段),按照该字段除以某数后取余的方法对数据表中的数据进行分类。
又如,从目标数据表中选取数据类型为字符型的字段,获取该字段字符的哈希值,按照该哈希值除以某数后取余的方法对数据表中的数据进行分类。或者,从所述哈希值中选取数位,按照选取的数位的数值对数据表中的数据进行分类。
下面以一个具体的例子详细说明建立分类规则的方法。
如图4所示。在当前数据库中有T0、T1、T2、T3…T(n+1)共n+2张表。建立每张目标数据表的分类规则。其中,T0表的分类规则记为rule1.0即401,T1表的分类规则记为rule1.1即402,T2表的分类规则记为rule1.2即403,T3表的分类规则记为rule1.3即404,T(n+1)表的分类规则记为rule1.(n+1)即405。
根据分类规则rule1.0,依据T0表在数据库中增加数据表T0_0、T0_1。根据分类规则rule1.2,依据T2表在数据库中增加数据表T2_0、T2_1。根据分类规则rule1.(n+1),依据T(n+1)表在数据库中增加数据表T(n+1)_0。
随着数据量的增长,在某些情况下,依据T(n+1)表在数据库中增加数据表T(n+1)_0后,T(n+1)_0表中的数据量也达到预设数据量。此时,选取T(n+1)_0表作为目标数据表,建立该表的分类规则rule2.(n+1)即406。
根据分类规则rule2.(n+1),依据T(n+1)_0表在数据库中增加数据表T(n+1)_0_0。
一般情况下,图4所示的数据表,T0、T1、T2、T3…T(n+1)表的层次为1,处于该数据库的第1层。T0_0、T0_1、T2_0、T2_1、T(n+1)_0表的层次为2,处于该数据库的第2层。T(n+1)_0_0表的层次为3,处于该数据库的第3层。其中,T0、T1、T2、T3…T(n+1)表为根数据表。
在另一些情况下,图4所示的数据表,T0、T1、T2、T3…T(n+1)表的层次为3,处于该数据库的第3层。T0_0、T0_1、T2_0、T2_1、T(n+1)_0表的层次为2,处于该数据库的第2层。T(n+1)_0_0表的层次为1,处于该数据库的第1层。其中,T0、T1、T2、T3…T(n+1)表为根数据表。
图4所示的分类规则具体如下面的表1所示。
表1
divRuleCode |
num |
tableNamePrefix |
Level |
Remark |
rule1.0 |
2 |
T0 |
1 |
ID%2 |
rule1.2 |
2 |
T2 |
1 |
ID%2 |
rule1.(n+1) |
1 |
T(n+1) |
1 |
ID%1 |
rule2.(n+1) |
1 |
T(n+1)_0 |
2 |
ID%1 |
表1中:
divRuleCode表示分类规则的编码,用于标识分类规则;
num表示需要在数据库中增加数据表的数量;
tableNamePrefix为默认的表名前缀,即目标数据表的表名;
Level表示目标数据表所处的层次,即tableNamePrefix表所处的层次;
Remark用于描述分类规则所对应的分表方法。例如选取数据表的ID字段,按照该字段除以某数后取余的方法在数据库中增加数据表。或者,选取数据表的账户的登录名字段,通过对账户的登录名字段取哈希值(hash)的方法在数据库中增加数据表。
在某些实施方式中,可以预先设定分类规则模型。当需要建立某张数据表的分类规则时,可以直接根据分类规则模型建立该数据表的分类规则。分类规则模型如下面的表2所示。
表2
属性 |
数据类型 |
描述 |
divRuleCode |
字符串 |
分类规则的编码 |
Num |
数值 |
分类数量 |
tableNamePrefix |
字符串 |
默认的表名前缀 |
Level |
数值 |
层次 |
Remark |
字符串 |
分类方法 |
由于目标数据表与依据该目标数据表增加的数据表均存储的是同一种类的数据,例如均存储的是A省的订单数据。因此,当需要查找(还可以是其它操作,例如删除和修改)A省的订单数据时,需要首先在目标数据表中查找,然后在增加的数据表中查找。在某一实施方式中,在依据数据表分类规则在数据库中增加数据表之后,建立该数据表的属性数据。根据每张数据表的属性数据可以快速的判断出在该数据表中是否存在需要查找的数据,从而节省查找操作的时间。在一些情况下,数据表的属性数据如下面的表3所示。
表3
属性 |
数据类型 |
描述 |
tableName |
字符串 |
表名 |
levelMaxId |
数值 |
表中某一字段数据的最大值 |
levelMinId |
数值 |
表中某一字段数据的最小值 |
表3中:
tableName表示数据表的表名前缀,即数据表的表名;
levelMaxId表示数据表中某一字段数据的最大值;
levelMinId表示数据表中某一字段数据的最小值。
例如,当需要在数据表中查找数据时,可以首先将该数据的数值与levelMaxId和levelMinId进行比较。若该数据的数值在levelMaxId和levelMinId之间,则说明在该数据表中存在该数据。若该数据的数值不在levelMaxId和levelMinId之间,则说明在该数据表中不存在该数据,此时,可以不在该数据表中进行查找,从而节省了查找的时间。
在某一实施方式中,可以建立一个存储模块。存储模块用于保存分类规则数据和数据表的属性数据。
S302:从数据库中选取目标数据表。
S303:从分类规则数据中获取目标数据表的分类规则。
S304:根据分类规则在数据库中增加数据表。
步骤S302中选取目标数据表的方法与步骤S201中的方法相类似。
由于步骤S301已建立数据表的分类规则数据,因此在步骤S303中,可以根据选取的目标数据表的表名,获取与该目标数据表的分类规则。例如,根据选取的目标数据表的表名,查找分类规则数据中tableNamePrefix的值(即tableNamePrefix的表名)与所述目标数据表的表名相同的分类规则。
在某一实施方式中,分类规则数据存储在存储模块中,因此需要从存储模块中获取分类规则。
步骤S304中,根据分类规则中num的值,在数据库中增加数据表。增加数据表后,目标数据表中的数据保持不变,不在该目标数据表中写入新的数据,而是对该目标数据表进行数据的查询、修改或删除的操作。增加的数据表用于写入新的数据,同时,增加的数据表也可用于数据的查询、修改或删除的操作。
在某一实施方式中,增加数据表后,建立目标数据表的属性数据,以便于数据的查询、修改和删除操作。
本实施例的技术方案,预先建立数据库每张数据表的分类规则,并生成分类规则数据。在数据库的运行过程中,每隔一段时间获取数据库中数据表的数据量情况。当某一数据表达到预设数据量时,从分类规则数据中获取该数据表的分类规则,依据该分类规则在数据库中增加数据表,从而实现了在数据库运行的过程中,灵活动态的进行数据库扩容。
当然,在一些情况下,也可以不用每隔一段时间获取数据库中数据表的数据量情况,而是在某个时间点从分类规则数据中获取该数据表的分类规则,依据该分类规则在数据库中增加数据表。这样,可以将不同时间段的数据存储到不同的数据表中,从而有利于数据的分析查找。
本申请实施例还提供了一种访问数据库的方法,用于在数据库扩容之后,对数据库进行访问。如图5所示,为了详细说明本实施例的方法,访问数据库的方法划分为由接收模块、解析模块、计算模块和执行模块等4个功能模块执行。本申请实施例提供的一种访问数据库的方法包括如下的步骤:
S501:接收模块接收客户端访问数据库的请求,访问请求中携带有目标数据和访问类型。
所述数据库中包含有按照图2或图3所对应的实施例中的数据库分表方法增加的数据表。一般情况下,访问请求包括修改访问请求、写访问请求(增加访问请求)、查找访问请求和删除访问请求。访问请求中一般携带有目标数据,即携带有需要增加的数据、需要删除的数据、需要查找的数据或需要修改的数据。
所述客户端一般用于发送访问数据库的请求。
在某一实施方式中,所述访问请求通过SQL语句执行,即SQL语句中携带有目标数据和访问请求的类型。
S502:接收模块将接收到的访问请求传送给解析模块。
S503:解析模块对所述访问请求进行解析,得到访问请求的类型和目标数据。
解析模块从接收到的访问请求中,分析出访问请求的类型,即分析出所述访问请求是修改访问请求、写访问请求、查找访问请求或删除访问请求。
所述目标数据一般是指访问请求所需要的数据,一般指在数据库中需要进行修改、增加、查询或删除的数据。
S504:解析模块将目标数据传送给计算模块。
S505:计算模块接收到目标数据后,向存储模块获取分类规则,并依据分类规则对所述目标数据进行计算,得到数据表集合。
所述存储模块存储有数据表的分类规则和属性数据。
一般情况下,数据库中包含有多张数据表,每张数据表具有不同的层次。从根据数据表开始逐层获取数据表的分类规则,针对每一层数据表的分类规则,利用该分类规则对目标数据进行计算,从而得到数据表。将根据各层数据表的分类规则得到的数据表作为数据表集合。
例如,某一数据表的分类规则为取账户登录名哈希值最后一位数的数值,根据该分类规则在数据库中增加了数据表T_0、T_1、T_2、T_3、T_4、T_5、T_6、T_7、T_8、T_9,其中,T_0表中存储账户登录名哈希值最后一位数的数值为0的数据,T_1表中存储账户登录名哈希值最后一位数的数值为1的数据,T_2表中存储账户登录名哈希值最后一位数的数值为2的数据,以此类推,T_9表中存储账户登录名哈希值最后一位数的数值为9的数据。
计算该目标数据中账户登录名的哈希值,然后获取该哈希值最后一位数的数值,根据该数值获取上述T_0至T_9中数据表的表名。
S506:计算模块将数据表集合传递给执行模块。
S507:执行模块接收到数据表集合后,向解析模块请求获取访问请求的类型和目标数据。
S508:解析模块将访问请求的类型和目标数据传送给执行模块。
S509:执行模块根据目标数据、访问请求的类型,以及数据表集合中的数据表,生成新的访问请求。
在某些实施方式中,执行模块根据目标数据、访问请求的类型,以及数据表集合中的数据表,生成新的SQL语句。
所述新的访问请求,包括写入、修改、查找或删除目标数据。
S510:执行模块根据新的访问请求,依据目标数据向数据表集合中的数据表执行相应的操作。
当新的访问请求为向数据表中增加目标数据时,则获取数据表集合中层次最高的数据表,然后向该数据表中增加目标数据。
当新的访问请求为在数据表中查询、修改、删除目标数据时,则首先获取数据表集合中层次最低的数据表,然后在该数据表中查询目标数据。若查找到,则在该数据表中进行进一步的修改或删除操作,访问过程执行完毕。
若没有查找到,则进一步获取数据表集合中相邻的较高层的数据表,然后在该数据表中查询目标数据。若查找到,则在该数据表中进一步修改或删除该目标数据,访问过程执行完毕。若没有查找到,则进一步获取数据表集合中相邻的较高层的数据表。以此类推,直到数据表集合中层次最高的数据表为止。
在某一实施方式中,通过对比目标数据表的属性数据,可以进一步节省查找、修改、删除目标数据所需的时间。下面以一个具体的例子详细说明。
如图6所示,为数据库中的订单数据表。刚开始时,在order数据表中存储订单数据,order数据表为第0层数据表。
随着数据量的增长,order数据表达到预设数据量。此时,从存储模块获取order数据表的分类规则601。根据分类规则601,在数据库中增加数据表order0、order1、order2…order9。order0至order9数据表为第1层数据表。分表后,order数据表不再写入新的数据。同时,统计order数据表中的数据,生成该数据表的属性数据。
随着数据量的增长,order0和order1数据表达到预设数据量。此时,从存储模块获取order0数据表的分类规则602,根据分类规则602,在数据库中增加数据表order0_1、order0_2…order0_9。从存储模块获取order1数据表的分类规则603,根据分类规则603,在数据库中增加数据表order1_0、order1_1…order1_9。order0_1至order0_9数据表,以及order1_0至order1_9为第2层数据表。分表后,order0和order1数据表不再写入新的数据。同时,统计order0和order1数据表中的数据,生成order0和order1数据表的属性数据。
随着数据量的增长,order1_0数据表达到预设数据量。此时,从存储模块获取order1_0数据表的分类规则604。根据分类规则604,在数据库中增加数据表order1_0_0、order1_0_1…order1_0_9。order1_0_0至order1_0_9数据表为第3层数据表。分表后,order1_0数据表不再写入新的数据。同时,统计order1_0数据表中的数据,生成该数据表的属性数据。
随着数据量的增长,order1_0_0数据表达到预设数据量。此时,从存储模块获取order1_0_0数据表的分类规则605。根据分类规则605,在数据库中增加数据表order1_0_0_0、order1_0_0_1…order1_0_0_9。order1_0_0_0至order1_0_0_9数据表为第4层数据表。分表后,order1_0_0数据表不再写入新的数据。同时,统计order1_0_0数据表中的数据,生成该数据表的属性数据。
601、602、603、604和605的分类规则,具体如下面的表4所示。
表4
order0、order1、order1_0、order1_0_0数据表的属性数据如下面的表5所示。
表5
接收模块接收客户端访问数据库的请求,并将接收到的访问请求传送给解析模块。解析模块对所述访问请求进行解析,得到访问请求的类型和目标数据。
若目标数据登录名的哈希值为80089891,访问请求的类型为写访问请求。则写入该目标数据的过程如下:
1)从存储模块中找出level为0的分类规则。该分类规则为rule_order_zero_hash_10,所对应的分类方法为账户登录名哈希值%10的数值。由于80089891%10的结果为1,因此,得到数据表order1,并将order1表的表名存储起来。
2)从存储模块中找出level为1并且tableNamePrefix为order1的分类规则。该分类规则为rule_order1_first_hash_10,所对应的分类方法为账户登录名哈希值的第2位数的数值。由于80089891的第3位数的数值字为0,因此,得到数据表order1_0,并将order1_0表的表名存储起来。
3)从存储模块中找出level为2并且tableNamePrefix为order1_0的分类规则。该分类规则为rule_order1_0_second_hash_10,所对应的分类方法为账户登录名哈希值的第3位数的数值。由于80089891的第3位数的数值字为0,因此,得到数据表order1_0_0,并将order1_0_0表的表名存储起来。
4)从存储模块中找出level为3并且tableNamePrefix为order1_0_0的分类规则。该分类规则为rule_order1_0_0_third_hash_10,所对应的分类方法为账户登录名哈希值的第3位数的数值。由于80089891的第3位数的数值字为0,因此,得到数据表order1_0_0_0,并将order1_0_0_0表的表名存储起来。
5)从存储模块中找出level为4并且tableNamePrefix为order1_0_0_0的分类规则。由于存储模块中没有所要查找的分类规则,因此直接返回,并停止查找数据表。
由于访问请求的类型为写访问请求,因此从计算得到的数据表中找出层次最高的数据表。即从order、order1、order1_0、order1_0_0和order1_0_0_0数据表中找出层次最高的数据表,从而得到数据表order1_0_0_0。最终,向order1_0_0_0数据表中写入目标数据。
若目标数据登录名的哈希值为80089891,访问请求的类型为查询访问请求。则查询该目标数据的过程如下:
1)从存储模块中找出level为0的分类规则。该分类规则为rule_order_zero_hash_10,所对应的分类方法为账户登录名哈希值%10的数值。由于80089891%10的结果为1,因此,得到数据表order1。order1数据表中数据的哈希值的区间范围为111~888881,80089891不在该区间范围内。因此可以快速的判断出order1数据表中不存在所需要查找的目标数据,从而放弃order1数据表。
2)从存储模块中找出level为1并且tableNamePrefix为order1的分类规则。该分类规则为rule_order1_first_hash_10,所对应的分类方法为账户登录名哈希值的第2位数的数值。由于80089891的第3位数的数值字为0,因此,得到数据表order1_0。order1_0数据表中数据的哈希值的区间范围为101~90989891,80089891在该区间范围内。因此可以快速的判断出order1_0数据表中有可能存在所需要查找的目标数据(由于order1_0表中的哈希值并不是连续的,因此order1_0表中也有可能不存在所需要查找的目标数据),从而将order1_0表的表名存储起来。
3)从存储模块中找出level为2并且tableNamePrefix为order1_0的分类规则。该分类规则为rule_order1_0_second_hash_10,所对应的分类方法为账户登录名哈希值的第3位数的数值。由于80089891的第3位数的数值字为0,因此,得到数据表order1_0_0。order1_0_0数据表中数据的哈希值的区间范围为1001~90089891,80089891在该区间范围内。因此可以快速的判断出order1_0数据表中有可能存在所需要查找的目标数据,从而将order1_0_0表的表名存储起来。
4)从存储模块中找出level为3并且tableNamePrefix为order1_0_0的分类规则。该分类规则为rule_order1_0_0_third_hash_10,所对应的分类方法为账户登录名哈希值的第3位数的数值。由于80089891的第3位数的数值字为0,因此,得到数据表order1_0_0_0。此时,未在存储模块中找到order1_0_0_0的哈希值区间,表明order1_0_0_0表中的数据还没有达到预设的数据量,即还可以向order1_0_0_0表中写入新的数据。order1_0_0_0数据表中有可能存在所需要查找的目标数据,从而将order1_0_0_0表的表名存储起来。
5)从存储模块中找出level为4并且tableNamePrefix为order1_0_0_0的分类规则。由于存储模块中没有所要找的分类规则,因此直接返回,并停止查找数据表。
由于访问请求的类型为查询访问请求,因此最终需要依次从order1_0、order1_0_0、和order_1_0_0_0数据表中查询目标数据。
若目标数据登录名的哈希值为80089891,访问请求的类型为修改访问请求或删除访问请求,则修改或删除该目标数据的过程与查询该目标数据的过程相类似,具体可参考以上的叙述。
最后,需要说明的是,一般来说,“理想”的数据库扩容方案应该努力满足以下几个要求:
1)最好不迁移数据;
2)能均匀的分布数据读写,避免“热点”问题;
3)保证对已经达到存储上限的数据表不再写入数据;
4)可以根据需求不同采用不同的字段作为分表的路由规则,而不是限定以ID作为条件。
本申请实施例的数据库扩容方法,在数据库中增加数据表后,不将目标数据表中的数据迁移到增加的数据表中。对于目标数据表,只进行查询、修改、删除操作,对于增加的数据表,进行增加、查询、修改、删除操作。从而避免了数据的迁移,以及保证了对已经达到存储上限的数据表不再写入数据。
本申请实施例的数据库扩容方法,减少了单张数据表中的数据量。并且根据分类规则对目标数据进行计算,从而定位到不同的数据表,避免了对同一张数据表进行大量的读写操作,从而避免了“热点”问题。并且所述分类规则不仅可以根据数据表中的ID字段建立,还可以根据数据表中的字符型字段(例如登录名)建立,从而保证了可以根据需求不同采用不同的字段作为分类规则。
本申请实施例还提供一种数据库扩容装置,如图7所示,包括:
第一选取模块701,用于从数据库中选取第一数据表;
第一分类模块702,用于从第一数据表中选取字段,根据所述字段获取第一数据表中数据的分类数;
建立模块703,用于根据所述分类数在数据库中建立第二数据表,所述第二数据表的结构与所述第一数据表的结构相同;
保持模块704,用于在建立第二数据表后,保持第一数据表中的数据,当需要在数据库中写入新的数据时,将所述新的数据写入到第二数据表中。
在某些实施方式中,该装置还包括第二生成模块705,用于获取第一数据表的字段中数据的最大值和最小值,根据最大值和最小值生成第一数据表的属性数据。
本申请实施例还提供另一种数据库扩容装置,如图8所示,包括:
第一生成模块801,用于根据数据库中每张数据表的分类规则生成分类规则数据;
第一选取模块701,用于从数据库中选取第一数据表;
第二选取模块802,用于根据所述第一数据表从分类规则数据中选取分类规则;
第二分类模块803,用于根据选取的分类规则得到第一数据表中数据的分类数;
建立模块703,用于根据所述分类数在数据库中建立第二数据表,所述第二数据表的结构与所述第一数据表的结构相同;
保持模块704,用于在建立第二数据表后,保持第一数据表中的数据,当需要在数据库中写入新的数据时,将所述新的数据写入到第二数据表中。
在某些实施方式中,该装置还包括第二生成模块705,用于获取第一数据表的字段中数据的最大值和最小值,根据最大值和最小值生成第一数据表的属性数据。
在某些实施方式中,该装置还包括存储模块804,用于保存所述分类规则数据。
本申请实施例还提供一种访问数据库的装置,如图9所示,包括:
接收模块901,用于接收访问数据库中数据表的请求;
解析模块902,用于对访问请求进行解析,得到操作方式和第一数据;
计算模块903,用于从根据数据表开始逐层获取数据表的分类规则,分别根据各个分类规则和第一数据得到数据表,将根据各个分类规则得到的数据表作为数据表集合;
执行模块904,用于根据所述操作方式和第一数据,对数据表集合中的数据表进行操作。
在某些实施方式中,执行模块904还包括判断单元905,用于获取数据表的属性数据,从属性数据中获取该数据表中数据的最大值和最小值,根据最大值和最小值判断在该数据表中查询第一数据。
在20世纪90年代,对于一个技术的改进可以很明显地区分是硬件上的改进(例如,对二极管、晶体管、开关等电路结构的改进)还是软件上的改进(对于方法流程的改进)。然而,随着技术的发展,当今的很多方法流程的改进已经可以视为硬件电路结构的直接改进。设计人员几乎都通过将改进的方法流程编程到硬件电路中来得到相应的硬件电路结构。因此,不能说一个方法流程的改进就不能用硬件实体模块来实现。例如,可编程逻辑器件(Programmable Logic Device,PLD)(例如现场可编程门阵列(Field Programmable GateArray,FPGA))就是这样一种集成电路,其逻辑功能由用户对器件编程来确定。由设计人员自行编程来把一个数字系统“集成”在一片PLD上,而不需要请芯片制造厂商来设计和制作专用的集成电路芯片2。而且,如今,取代手工地制作集成电路芯片,这种编程也多半改用“逻辑编译器(logic compiler)”软件来实现,它与程序开发撰写时所用的软件编译器相类似,而要编译之前的原始代码也得用特定的编程语言来撰写,此称之为硬件描述语言(Hardware Description Language,HDL),而HDL也并非仅有一种,而是有许多种,如ABEL(Advanced Boolean Expression Language)、AHDL(Altera Hardware Description Language)、Confluence、CUPL(Cornell University Programming Language)、HDCal、JHDL(Java HardwareDescription Language)、Lava、Lola、MyHDL、PALASM、RHDL(Ruby Hardware DescriptionLanguage)等,目前最普遍使用的是VHDL(Very-High-Speed Integrated Circuit HardwareDescription Language)与Verilog2。本领域技术人员也应该清楚,只需要将方法流程用上述几种硬件描述语言稍作逻辑编程并编程到集成电路中,就可以很容易得到实现该逻辑方法流程的硬件电路。
控制器可以按任何适当的方式实现,例如,控制器可以采取例如微处理器或处理器以及存储可由该(微)处理器执行的计算机可读程序代码(例如软件或固件)的计算机可读介质、逻辑门、开关、专用集成电路(Application Specific Integrated Circuit,ASIC)、可编程逻辑控制器和嵌入微控制器的形式,控制器的例子包括但不限于以下微控制器:ARC 625D、AtmelAT91SAM、Microchip PIC18F26K20以及Silicone Labs C8051F320,存储器控制器还可以被实现为存储器的控制逻辑的一部分。
本领域技术人员也知道,除了以纯计算机可读程序代码方式实现控制器以外,完全可以通过将方法步骤进行逻辑编程来使得控制器以逻辑门、开关、专用集成电路、可编程逻辑控制器和嵌入微控制器等的形式来实现相同功能。因此这种控制器可以被认为是一种硬件部件,而对其内包括的用于实现各种功能的装置也可以视为硬件部件内的结构。或者甚至,可以将用于实现各种功能的装置视为既可以是实现方法的软件模块又可以是硬件部件内的结构。
上述实施例阐明的系统、装置、模块或单元,具体可以由计算机芯片或实体实现,或者由具有某种功能的产品来实现。
为了描述的方便,描述以上装置时以功能分为各种单元分别描述。当然,在实施本申请时可以把各单元的功能在同一个或多个软件和/或硬件中实现。
通过以上的实施方式的描述可知,本领域的技术人员可以清楚地了解到本申请可借助软件加必需的通用硬件平台的方式来实现。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品可以存储在存储介质中,如ROM/RAM、磁碟、光盘等,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本申请各个实施例或者实施例的某些部分所述的方法。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于系统实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
本申请可用于众多通用或专用的计算机系统环境或配置中。例如:个人计算机、服务器计算机、手持设备或便携式设备、平板型设备、多处理器系统、基于微处理器的系统、置顶盒、可编程的消费电子设备、网络PC、小型计算机、大型计算机、包括以上任何系统或设备的分布式计算环境等等。
本申请可以在由计算机执行的计算机可执行指令的一般上下文中描述,例如程序模块。一般地,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。也可以在分布式计算环境中实践本申请,在这些分布式计算环境中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于包括存储设备在内的本地和远程计算机存储介质中。
虽然通过实施例描绘了本申请,本领域普通技术人员知道,本申请有许多变形和变化而不脱离本申请的精神,希望所附的权利要求包括这些变形和变化而不脱离本申请的精神。