具体实施方式
为使本申请的目的、技术方案和优点更加清楚,下面将结合本申请具体实施例及相应的附图对本申请技术方案进行清楚、完整地描述。显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
为了减少第一服务器在获取数据时与第二服务器交互的次数,本申请实施例中部署第二服务器对应的数据存储引擎,该数据存储引擎直接对外开放接口,由第二服务器将其对应的数据库中的数据同步到数据存储引擎,第一服务器可直接从数据存储引擎中获取数据,而无需调用第二服务器,再通过第二服务器获取数据库中的数据。下面通过图2详细说明第二服务器将数据库中的数据同步到数据存储引擎中的过程。
图2为本申请实施例提供的数据同步过程,具体包括以下步骤:
S201:在数据库中确定出更新的数据。
在本申请实施例中,数据库中的数据通常存在更新的情况(如,将新的数据增加到数据库中、或者在数据库中删除某一数据、或者在数据库中修改某一数据),为了保证数据存储引擎中数据也是最新的,与数据库中的保持一致,因此,如果数据库中的数据出现了更新的情况,则需要将数据库中更新的数据同步到数据存储引擎中,而执行整个数据同步过程是由第二服务器完成的(由于本申请涉及两个不同的服务器,这两个服务器在完成本申请所述方法的过程中所实现的功能也是不同的,因此,在此用第一服务器与第二服务器进行区分,所述第二服务器主要用于数据同步,所述第一服务器主要用于数据获取)。
在同步的过程中,第一步就要在数据库中确定出更新的数据,在确定更新数据之前,可以采用在更新的数据中添加更新标识符的方式来标识哪些数据发生了更新,也就是说,可以在向数据库添加更新的数据之前,先在携带更新的数据的逻辑语句中添加更新标识符,如,在逻辑更新语句:update my_table setcolumn1=‘XXX’where column2=‘YYY’中添加“oper_status=-1”(“oper_status=-1”中的“-1”即为更新标识符),得到携带有更新标识符的逻辑更新语句:update my_table set column1=‘XXX’oper_status=-1wherecolumn2=‘YYY’,这样,第二服务器可直接根据携带更新标识符(如,oper_status=-1)的逻辑更新语句判断出哪个数据存在更新的情况。
例如,假设提供电子书籍的服务商B对应的数据库b中存储的数据如图3所示,服务商B需要将如图3所示数据中的《悲惨世界》对应的售价由“5RMB”更新为“4RMB”(更新后的数据如图4所示),因此,服务商B通过上述逻辑更新语句将图3所示的售价更新为“4RMB”,并向携带更新数据的逻辑语句中添加更新标识符(如,oper_status=-1)。
服务商B对应的服务器2(即,第二服务器)在进行数据同步时,通过oper_status=-1识别出更新的数据为数据4。
S202:根据更新的数据,确定出所述数据对应的数据属性。
在本申请实施例中,第二服务器在通过逻辑更新语句确定出更新的数据后,再确定出更新的数据对应的数据属性,所述数据属性表征数据的某一特征,主要包括属性名和属性值,如图3所示的,价格=5RMB,名称=基督山伯爵等。
延续上例,服务器2确定出数据库b中存储的如图4所述中更新的数据4,因此,确定出更新的数据对应的数据属性为:名称=悲惨世界、作者=雨果、价格=4RMB、页数=359。
S203:在预先保存的各数据主键中,确定出包含所述数据属性的数据主键。
在本申请实施例中,为了后续能够快速查找数据,数据存储引擎可以采用分类存储数据的方式存储数据,具体可以采用Key-Value形式存储数据,其中,数据主键(即,Key)可以是预先确定的(具体可预先将查询次数或频率较高的数据主键设定为数据存储引擎中的数据主键),每个数据主键由数据属性确定。也就是说,可以将任一数据属性作为数据主键(如,将图3所示的价格=5作为数据主键),也可以将数据属性中的至少一个作为数据主键(如,将图5所示的作者=雨果以及价格=5RMB组合在一起作为数据主键),无论怎样组合,都是为了通过数据主键能够快速的查询这一类的数据。
第二服务器在确定出更新数据的各数据属性后,可查找预先保存的各数据主键,确定出包含数据属性的数据主键。
延续上例,假设“价格=4RMB”、“价格=5RMB”、“作者=雨果”、“作者=雨果以及价格=4RMB”、“作者=雨果以及价格=5RMB”是预先保存的各数据主键中的五个数据主键,而通过上述S202确定出的更新数据(即,数据4)的数据属性为“名称=悲惨世界、作者=雨果、价格=4RMB、页数=359”,因此,服务器2根据预先保存的各数据主键,确定出包含数据4的数据属性的数据主键为“价格=4RMB”(包含数据属性“价格=4RMB”、“作者=雨果”(包含数据属性“作者=雨果”)、“作者=雨果以及价格=4RMB”(包含数据属性“作者=雨果”和“价格=4RMB”),而数据主键“价格=5RMB”、“作者=雨果以及价格=5RMB”,不包含数据4的任何数据属性,因此,包含数据4的数据属性的数据主键为“价格=4RMB”、“作者=雨果”和“作者=雨果以及价格=4RMB”。
S204:根据确定出的数据主键,在数据库中查找确定出的数据主键对应的所有数据。
在本申请实施例中,第二服务器在确定出数据主键后,在数据库中查找出数据主键都对应了哪些数据,并将这些确定出的数据提取出来。
继续沿用上例,服务器2根据数据4确定出的数据主键为“价格=4RMB”、“作者=雨果”、“作者=雨果以及价格=4RMB”,在存储数据1~数据6的数据库b中确定出数据主键为“价格=4RMB”对应的数据有数据3、数据4、数据5。确定出数据主键为“作者=雨果”对应的数据有数据2、数据4、数据5。确定出数据主键为“作者=雨果以及价格=4RMB”对应的数据有数据4、数据5,并将上述确定出各数据提取出来。
S205:将查找到的所有数据同步到数据存储引擎中。
在实际应用中,第二服务器是将数据同步到数据存储引擎中,而数据存储引擎中存储的数据形式与数据库中存储的数据形式不同,数据存储引擎是采用Key-Value形式存储数据的,一个Key对应至少一个数据,一个Key所对应的数据可存储在一个数据表中,该数据表是一个不可分割的整体存储在Value中,如图5所示,每个Key对应的数据可能会部分相同。
由于本申请实施例中的数据存储引擎采用上述如图5所示的形式存储数据,因此,当数据库中的某一数据发生了变化时,就需要将包含该数据的数据属性的数据主键所对应的所有数据同步到数据存储引擎中,而不能只单单同步发生变化的数据,从而,第二服务器通过上述步骤S204将包含更新的数据的数据属性的数据主键所对应的所有数据都提取出来后,即可通过步骤S205,将提取出的数据同步到数据存储引擎中。
延续上例,服务器2将数据主键为“价格=4RMB”对应的数据3、数据4、数据5提取出来,并将上述确定出的数据重新组成如图6所示的数据表,将该数据表作为Value,将“价格=4RMB”作为Key,从而形成Key-Value的存储格式;
将数据主键为“作者=雨果”对应的数据2、数据4、数据5提取出来,并将上述确定出的数据重新组成如图7所示的数据表,将该数据表作为Value,将“作者=雨果”作为Key;
将数据主键为“作者=雨果以及价格=4RMB”对应的数据4、数据5提取出来,并将上述确定出的数据重新组成如图8所示的数据表,将该数据表作为Value,将“作者=雨果以及价格=4RMB”作为Key,从而形成Key-Value的存储格式,并将上述确定出的所有数据(即,如图6~8所示的数据)更新到数据存储引擎b中。
通过上述方法,可以将数据库中已更新的数据,同步到第二服务器对应的数据存储引擎中,这样可以能够很好的保证数据库中的数据与数据存储引擎中的数据一致。
另外,第二服务器在从数据库中确定出更新的数据后,可将更新的数据中的更新标识符删除掉,这样就表示该更新的数据已经被第二服务器纳入数据同步的范围,并在这一次的数据同步操作中会将该更新的数据同步到数据存储引擎中,以避免下一次第二服务器依然对该更新的数据进行数据同步操作。具体的,可以直接将示例的“update my_table set column1=‘XXX’oper_status=-1where column2=‘YYY’”中的“oper_status=-1”改成“oper_status=0”,用以表示该更新的数据中的更新标识符已经被删除。无论什么样的方法,只要能够避免第二服务器在下一次数据同步操作中,依然对这一次确定出的更新的数据进行数据同步操作即可。
在本申请实施例中,对于上述S201~S205中所描述的例子中,预先保存的数据主键是“价格=4RMB”、“价格=5RMB”、“作者=雨果”、“作者=雨果以及价格=4RMB”、“作者=雨果以及价格=5RMB”,也就是说,在没进行数据更新之前,数据存储引擎中存储的数据是如图5所示的。当数据库中的数据更新为如图4所示的数据表后,虽然只是将数据4中的“5RMB”改成了“4RMB”,但是实际上如图5所示的数据存储引擎中不仅仅是更新后的数据主键“价格=4RMB”、“作者=雨果”、“作者=雨果以及价格=4RMB”各自对应的数据发生了变化,而且更新前的主键对应的数据也发生了变化了(即,悲惨世界的价格已经由5RMB更新为了4RMB,因此更新前的数据主键“价格=5RMB”对应的数据中不应存在悲惨世界),因此,在数据同步时,不能单单只是根据更新后的数据进行数据同步,而且还要确定出更新前的数据,并根据更新前的数据也进行同步。即,第二服务器在确定更新的数据时,需要在数据库中确定出更新后的数据以及该更新后的数据对应的更新前的数据,共同作为更新的数据。
例如,假设图3所示的数据4是更新前的数据,图4所示的数据4是更新后的数据,则除了要根据如图4所示的更新后的数据4,采用如图2所示的方法进行数据同步以外,还需要根据图3所示的更新前的数据4也进行数据同步。即,确定出更新前的数据的数据主键“价格=5RMB”、“作者=雨果”、“作者=雨果以及价格=5RMB”,并在数据库中分别查找出数据主键“价格=5RMB”、“作者=雨果”、“作者=雨果以及价格=5RMB”对应的所有数据,并将分别确定出的数据与其对应的数据主键形成Key-Value的形式,并将其更新到数据存储引擎b中。
进一步的,在本申请实施例中,整个数据同步过程的整体框架是如图9所示的,图9中所示的第二服务器不仅仅是一个,而是一个第二服务器集群,这是由于在实际应用中,通常需要采用第二服务器集群来保证整个系统能够快速高效的运行,当然在实际应用中也可以是一个,而控制第二服务器完成数据同步过程的是由图9所示中的分布式定时任务调度中间件(以下简称为“中间件”)完成的,该中间件每隔预定的时间,可在第二服务器集群中选择出一台第二服务器,并向该第二服务器发送数据同步指令,第二服务器接收到数据同步指令后,则可根据S201~205进行数据同步操作,这样也避免第二服务器集群中的出现多个第二服务器同时对数据库中的数据进行同步的情况。
在实际应用中,由于将数据库中更新的数据同步到数据存储引擎中很可能存在因为网络不稳定而造成第二服务器即使获取到了所有要同步的数据,并将所有数据组成了Key-Value的存储格式,但是,无法成功将所有数据更新到数据存储引擎中的情况,针对于这种情况,在本申请实施例中,当第二服务器在未能成功将数据同步到数据存储引擎中时,则可根据同步失败的数据对应的数据主键(即,Key)生成同步失败消息,该同步失败消息中携带有同步失败的数据对应的数据主键(即,Key),并通过中间件将该同步失败消息发送给图9所示的第二服务器集群中的其他第二服务器,该其他第二服务器在接收到同步失败消息后,则可根据同步失败消息中携带的数据主键去数据库中查询相应的数据,并将查找到数据重新同步到数据存储引擎中。具体的,第二服务器确定同步失败的数据对应的数据主键,生成携带有同步失败的数据对应的数据主键的同步失败消息,将该同步失败消息发送给其他数据同步设备(即,第二服务器集群中的第二服务器),使其他数据同步设备根据该同步失败消息中携带的数据主键重新进行数据同步。
另外,当第二服务器在未能成功将数据同步到数据存储引擎中时,也可以可将同步失败的数据对应的数据主键(即,Key)放到一个失败列表中,并立刻再执行n次(n为正整数)数据同步,如果同样还是失败,则可根据同步失败的数据对应的数据主键生成同步失败消息,并通过中间件发送给第二服务器集群中的其他第二服务器。
在此需要说明的是,实际应用中可能存在下述情况:第二服务器集群中的一个第二服务器(以下称为第二服务器1)接收到同步失败消息的同时,中间件因到达预先设定的时间而向第二服务器集群中的另一第二服务器(以下称为第二服务器2)发送数据同步指令,使第二服务器2执行数据同步操作,并且同步失败消息中所涉及的数据主键与数据同步操作中所涉及的数据主键相一致。在这种情况下,第二服务器1接收到同步失败消息后,对某个数据执行数据同步操作,有可能第二服务器2接收到数据同步指令后,同样也要对该数据执行数据同步操作,这样,二者所同步的数据就发生了冲突,也就是说,第二服务器1与第二服务器2对相同的数据进行操作,但是第二服务器1在根据同步失败消息中携带的数据主键从数据库中获得某个数据后,用户有可能修改了该数据,即,数据库中该数据发生了更新,与此同时,第二服务器2接收到数据同步指令后,同样对该数据执行数据同步操作,而由于第二服务器1或者网络的原因,有可能会造成第二服务器1在将数据同步到数据存储引擎时比第二服务器2在将数据同步到数据存储引擎时慢,也就是说,第二服务器1同步的数据覆盖掉第二服务器2同步的数据。
例如,在上述实例中,假设服务器2(即,第二服务器)在将数据主键为“作者=雨果以及价格=4RMB”对应的如图8所示的数据同步到数据存储引擎中时,因为网络不稳定而造成同步失败了,因此,服务器2将数据主键“作者=雨果以及价格=4RMB”携带在同步失败消息上发送给如图9所示的中间件,并通过该中间件转发给服务器集群中的第二服务器3,第二服务器3在接收到服务器2发送过来的同步失败消息后,提取出同步失败消息中携带的数据主键“作者=雨果以及价格=4RMB”,并根据数据主键“作者=雨果以及价格=4RMB”在存储数据1~数据6的数据库b查找出如图8所示数据,并将“数据4”、“数据5”与对应的数据主键“作者=雨果以及价格=4RMB”组成Key-Value形式,但是与此同时,数据库中的数据5发生了更新(即,页数=350更新成页数=351),更新后的数据如图10所示,中间件因为到达预设的时间,从而在服务器集群中选择了第二服务器4,并向第二服务器4发送数据同步指令,第二服务器4在接收到数据同步指令后,在存储数据1~数据6的数据库b查找出发生更新的数据“数据5”,并确定出包含数据属性的一个数据主键“作者=雨果以及价格=4RMB”,根据该数据主键确定出如图11所示的数据。很明显可以看出,第二服务器3与第二服务器4都是根据相同的数据主键“作者=雨果以及价格=4RMB”在数据库中确定出的数据,但是图8所示的“数据5”与图11所示的“数据5”发生了冲突,第二服务器3在将如图8所示的数据同步到数据存储引擎b中之前,有可能第二服务器4已经将如图11所示的数据同步到数据存储引擎b中了,这样第二服务器3后续同步的如图8所示的数据就覆盖了服务器4同步的如图11所示的数据,造成了数据存储引擎中的数据不准确。
为了避免上述情况,在本申请实施例中,可以在数据库中存储的各数据中添加包含版本信息的标识(即,每个数据都携带有版本信息,以后每对存储的数据进行一次修改,该数据携带的版本信息就加1),第二服务器在提取出待同步的数据后,在将该待同步的数据更新到数据存储引擎之前,则可从数据库中查询即待同步的数据对应的版本信息,若待同步的数据中携带的版本信息与查询到的版本信息一致,则可以将待同步的数据更新到数据存储引擎中,若不一致,则可放弃同步。
继续沿用上例,假设在如图4所示的数据表中,“数据1~数据6”携带的版本信息为0,而数据库中的“数据5”被修改了,即,“数据5”发生了更新,更新后的数据如图10所示,“数据1~数据4与数据6”携带的版本信息为0,而“数据5”携带的版本信息为1,第二服务器3在将如图8中的数据同步到数据存储引擎中之前,从数据库中查找“数据5”对应的版本信息,查找的“数据5”对应的版本信息为1,而由于如图8所示的“数据5”携带的版本信息为0,因此,第二服务器3判定待同步的数据(即,数据5)携带的版本信息与数据库中相应数据的版本信息不一致,则可放弃同步。
上述为本申请实施例提供的数据同步方法,可以保证数据库中的数据与数据存储引擎中的数据一致,用户通过第一服务器获取数据时,则可直接访问第二服务器对应的数据存储引擎,获得准确的数据,图12所示的是用户通过第一服务器获取数据的过程。
图12为本申请实施例提供的数据获取过程,具体包括以下步骤:
S1201:第一服务器接收数据获取请求。
在本申请实施例中,第一服务器在接收到数据获取请求后,则先在第一服务器自身的数据库中进行查找,若没有查找到用户所需的数据,则可执行S1202。
例如,假设用户张三在提供音乐下载的服务商A的电子平台上,查找自己所需的音乐“默”,服务商A对外提供的电子平台1上的搜索区域输入“默”并点击确定,电子平台1向服务商A对应的服务器1(即,第一服务器)发送数据获取请求,服务器1在接收到数据获取请求后,在服务器1自身对应的数据库a中进行查找,但是未查找到,则可执行S1202。
S1202:根据预先保存的第二服务器对应的数据存储引擎接口,将所述数据获取请求发送给所述第二服务器对应的数据存储引擎,其中,所述数据存储引擎中存储的数据是从所述第二服务器对应的数据库中同步的。
在本申请实施例中,所述数据存储引擎具体可以是ldb数据存储引擎,用于通过上述如图2所示的方法与第二服务器对应的数据库同步数据。该数据存储引擎对外提供数据存储引擎的接口,以使得第一服务器通过数据存储引擎的接口访问该数据存储引擎,其中,所述数据存储引擎的接口预先保存在第一服务器中,第一服务器在自己的数据库中没有查找到用户所需的数据时,则可调取出第二服务器对应的数据存储引擎的接口,并通过数据存储引擎的接口查找到第二服务器对应的数据存储引擎,将数据获取请求发送给该数据存储引擎。
延续上例,假设服务商B预先建立了数据存储引擎2,并对外提供数据存储引擎2的接口,服务器1在数据库a中没有查找到音乐“默”,则可调取出数据存储引擎2的接口,通过数据存储引擎2的接口查找到数据存储引擎2,并将数据获取请求发送给数据存储引擎2。
S1203:接收所述数据存储引擎根据所述数据获取请求查找并返回的数据。
在本申请实施例中,数据存储引擎在接收到数据获取请求后,则查找数据获取请求对应的数据,并将查找到数据发送给第一服务器。
延续上例,数据存储引擎2在接收到服务器1发送的数据获取请求后,则查找数据获取请求对应的音乐“默“,并将查找到音乐”默“发送给服务器1。
通过上述方法,用户在获取数据时,不需要远程调用第二服务器,即,第一服务器不再通过第二服务器在该第二服务器对应的数据库中进行查找数据,而是直接访问数据存储引擎,并从数据存储引擎中获取自己所需的数据,这样在整个数据获取的过程中,降低了与第二服务器的交互次数,并且极大的降低了第二服务器的负荷,从而也降低了对第二服务器所提供的其他服务的影响。
在实际应用中,为了让用户能够更快的获取自己所需的数据,服务商可预先建立一个第一服务器对应的缓存,该缓存中可以存放一些临时数据。由于第一服务器在缓存中查找数据的速度远比在数据库中查找数据的速度要快,因此,当第一服务器在接收到数据获取请求后,可根据数据获取请求,在预设的缓存中查找用户所需的数据,在未查找到用户所需的数据时,将数据获取请求发送给第二服务器对应的数据存储引擎。具体的,第一服务器在该缓存中未查找到用户所需的数据时,可先在第一服务器自身的数据库中进行查找,如果没有查找到,则再调取出第二服务器对应的数据存储引擎的接口,通过数据存储引擎的接口查找到数据存储引擎,并将数据获取请求发送给数据存储引擎。其中,所述的缓存具体可以是mdb引擎。
另外,在上述建立缓存的基础之上,为了进一步的提高用户获取自己所需的数据的速度,第一服务器还可以将在第一服务器自身的数据库或者在第二服务器对应的数据存储引擎中查找到的数据提供给用户的同时,在缓存中备份一次,也即,第一服务器在数据存储引擎中查找到数据后,可将数据存储引擎返回的数据写入所述缓存中,这样,用户在下次同样需要获取该数据时可以直接在缓存中找到,提高了用户获取所需数据的速度。
结合本申请如图2和图12所示的方法,本申请还提供了一种获取数据的系统结构示意图,如图13所示。第二服务器用于将数据库中的数据同步到ldb数据存储引擎中,ldb数据存储引擎对外开放接口,第一服务器在获取数据时,先在mdb引擎(即,第一服务器对应的缓存)中获取,当未获取到数据时,再从ldb数据存储引擎中获取。
以上为本申请实施例提供的数据同步方法以及数据获取方法,基于同样的思路,本申请实施例还提供一种数据同步装置以及数据获取装置,如图14、图15所示。
图14为本申请实施例提供的数据同步装置结构示意图,所述装置包括:
确定数据模块1401,用于在数据库中确定出更新的数据;
确定属性模块1402,用于根据更新的数据,确定出所述数据对应的数据属性;
确定主键模块1403,用于在预先保存的各数据主键中,确定出包含所述数据属性的数据主键;
查找模块1404,用于根据确定出的数据主键,在数据库中查找确定出的数据主键对应的所有数据;
同步模块1405,用于将查找到的所有数据同步到数据存储引擎中。
所述装置还包括:
添加模块1406,用于在数据库中确定出更新的数据之前,当在所述数据库中更新数据时,在更新的数据中添加更新标识符,所述确定数据模块1401具体用于,在所述数据库中确定添加有所述更新标识符的数据。
所述确定数据模块1401还用于,在数据库中确定出更新的数据之后,删除所述更新的数据中添加的更新标识符。
所述确定数据模块1401具体用于,在数据库中确定出更新后的数据以及所述更新后的数据对应的更新前的数据,作为确定出的更新的数据。
所述同步模块1405还用于,若未成功将查找到的所有数据同步到数据存储引擎中,确定同步失败的数据对应的数据主键,生成携带有同步失败的数据对应的数据主键的同步失败消息,将所述同步失败消息发送给其他数据同步设备,使所述数据同步设备根据所述同步失败消息中携带的数据主键重新进行数据同步。
图14所示的装置具体可以位于第二服务器中。
图15为本申请实施例提供的数据获取装置结构示意图,所述装置包括:
第一接收模块1501,用于接收数据获取请求;
发送模块1502,用于根据预先保存的第二服务器对应的数据存储引擎接口,将所述数据获取请求发送给所述第二服务器对应的数据存储引擎,其中,所述数据存储引擎中存储的数据是从所述第二服务器对应的数据库中同步的;
第二接收模块1503,用于接收所述数据存储引擎根据所述数据获取请求查找并返回的数据。
所述发送模块1502具体用于,根据所述数据获取请求,在预设的缓存中查找相应的数据,在未查找到所述相应的数据时,将所述数据获取请求发送给所述第二服务器对应的数据存储引擎。
所述装置还包括:
写入模块1504,用于将所述数据存储引擎返回的数据写入所述缓存中。
所述数据存储引擎包括:ldb数据存储引擎。
图15所示的装置具体可以位于第一服务器中。
在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitorymedia),如调制的数据信号和载波。
还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、商品或者设备中还存在另外的相同要素。
本领域技术人员应明白,本申请的实施例可提供为方法、系统或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
以上所述仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。