CN110399104B - 数据存储方法、数据存储装置、电子设备、存储介质 - Google Patents
数据存储方法、数据存储装置、电子设备、存储介质 Download PDFInfo
- Publication number
- CN110399104B CN110399104B CN201910667581.7A CN201910667581A CN110399104B CN 110399104 B CN110399104 B CN 110399104B CN 201910667581 A CN201910667581 A CN 201910667581A CN 110399104 B CN110399104 B CN 110399104B
- Authority
- CN
- China
- Prior art keywords
- data
- value
- key
- target
- storage area
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F3/00—Input arrangements for transferring data to be processed into a form capable of being handled by the computer; Output arrangements for transferring data from processing unit to output unit, e.g. interface arrangements
- G06F3/06—Digital input from, or digital output to, record carriers, e.g. RAID, emulated record carriers or networked record carriers
- G06F3/0601—Interfaces specially adapted for storage systems
- G06F3/0602—Interfaces specially adapted for storage systems specifically adapted to achieve a particular effect
- G06F3/0608—Saving storage space on storage systems
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F3/00—Input arrangements for transferring data to be processed into a form capable of being handled by the computer; Output arrangements for transferring data from processing unit to output unit, e.g. interface arrangements
- G06F3/06—Digital input from, or digital output to, record carriers, e.g. RAID, emulated record carriers or networked record carriers
- G06F3/0601—Interfaces specially adapted for storage systems
- G06F3/0628—Interfaces specially adapted for storage systems making use of a particular technique
- G06F3/0638—Organizing or formatting or addressing of data
Abstract
本公开提供了一种数据存储方法、数据存储装置、电子设备及计算机可读存储介质,属于计算机技术领域。该方法包括:对初始的多维数据进行扁平化处理,得到键值数据,所述键值数据包括成对的键数据和值数据;将所述键数据或所述键数据的哈希值存储至第一存储区域的目标键存储单元;确定所述值数据的长度未超过字节阈值,则将所述值数据存储至第二存储区域的目标值存储单元,所述目标值存储单元与所述目标键存储单元具有关联;确定所述值数据的长度超过所述字节阈值,则将所述值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元。本公开可以显著压缩数据在内存中的占用资源。
Description
技术领域
本公开涉及计算机技术领域,尤其涉及一种数据存储方法、数据存储装置、电子设备及计算机可读存储介质。
背景技术
随着数据时代的来临,系统或程序所需要存储或维护的数据越来越丰富,特别是在游戏数据系统中,随着游戏的维护和新功能的开发,大量增长的数据需要一种合适的存储方法,以便于游戏启动时能够准确、快速的读取。
现有的数据存储方法,通常先由工作人员填写关于数据的表格,将表格转换为Python的字典结构,程序运行时,会将这些数据加载入内存中,使程序运行时能够被系统查询获取,并进行特定的显示和处理。但是,上述方法,通常较大程度上依赖于Python的字典结构,为了避免大量哈希冲突,存储时会预留大量冗余的内存空间,当数据被加载入内存成为Python字典结构后,程序所占内存会爆炸增长,导致程序运行时出现卡顿的情况。对于大部分程序而言,特别是游戏程序,内存的占用大小是一个非常关键的因素,而游戏程序出现卡顿则会影响玩家的游戏体验。因此,如何采用一种新的数据存储方式,以使数据在内存中所占的空间尽可能地被压缩,是现有技术亟待解决的问题。
需要说明的是,在上述背景技术部分公开的信息仅用于加强对本公开的背景的理解,因此可以包括不构成对本领域普通技术人员已知的现有技术的信息。
发明内容
本公开提供了一种数据存储方法、数据存储装置、电子设备及计算机可读存储介质,进而至少在一定程度上克服现有的数据存储方法中数据的内存占用较大的问题。
本公开的其他特性和优点将通过下面的详细描述变得显然,或部分地通过本公开的实践而习得。
根据本公开的一个方面,提供一种数据存储方法,包括:对初始的多维数据进行扁平化处理,得到键值数据,所述键值数据包括成对的键数据和值数据;将所述键数据或所述键数据的哈希值存储至第一存储区域的目标键存储单元;确定所述值数据的长度未超过字节阈值,则将所述值数据存储至第二存储区域的目标值存储单元,所述目标值存储单元与所述目标键存储单元具有关联;确定所述值数据的长度超过所述字节阈值,则将所述值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域。
在本公开的一种示例性实施例中,对初始的多维数据进行扁平化处理,得到键值数据,包括:获取多个初始数据字典,所述初始数据字典中包括多维数据;对所述多个初始数据字典中的所述多维数据分别进行扁平化处理,得到多个包括一维数据的中间数据字典;将所述多个中间数据字典合并,生成目标数据字典,并将所述目标数据字典中的一维数据分别确定为所述键值数据。
在本公开的一种示例性实施例中,所述方法还包括:在存储所述目标数据字典中的所有一维数据后,将已存储的键值数据输出为二进制数据文件。
在本公开的一种示例性实施例中,所述方法还包括:将所述第一存储区域的存储单元确定为键存储单元,所述目标键存储单元从所述键存储单元中确定;将所述第二存储区域划分为多个具有所述预设字节的值存储单元,所述目标值存储单元从所述值存储单元中确定。
在本公开的一种示例性实施例中,所述将所述第一存储区域的存储单元确定为键存储单元,包括:将所述第一存储区域划分为具有固定字节的所述键存储单元。
在本公开的一种示例性实施例中,所述确定所述值数据的长度超过所述字节阈值,则将所述值数据存储至第三存储区域的目标位置,包括:确定所述值数据的长度超过所述字节阈值,则判断所述值数据是否满足数据嵌套规则;如果所述值数据满足所述数据嵌套规则,则将所述值数据存储至第三存储区域的目标位置;所述数据嵌套规则包括:所述值数据为嵌套数据时,所述嵌套数据的层数不超过两层;所述值数据为两层嵌套数据时,所述值数据仅可为整型数据或浮点型数据;以及所述值数据的数据元素的类型唯一。
在本公开的一种示例性实施例中,所述值数据的类型为Python数据类型,在存储所述值数据之前,将所述值数据转换为C或C++数据类型。
在本公开的一种示例性实施例中,所述将所述值数据存储至第三存储区域的目标位置,包括:将所述值数据的长度和所述值数据写入所述第三存储区域的目标位置;其中,所述值数据位于所述值数据的长度之后,所述目标位置的偏移量用于指示所述目标位置的起始位置,所述值数据的长度具有固定字节,所述偏移量、所述固定字节和所述值数据的长度之和用于指示所述目标位置的结束位置。
在本公开的一种示例性实施例中,在得到所述键值数据之后,所述方法还包括:将所述键数据转换为无符号的整型数据,并计算所述整型数据的哈希值;采用求模式运算符与直接寻址确定所述哈希值的哈希索引;所述将所述键数据或所述键数据的哈希值存储至第一存储区域的目标键存储单元,包括:根据所述哈希索引在所述第一存储区域中确定所述目标键存储单元,将所述键数据的哈希值写入所述目标键存储单元。
在本公开的一种示例性实施例中,所述目标值存储单元通过以下步骤确定:将所述目标键存储单元的偏移量加上所述第一存储区域的长度,得到所述目标值存储单元的偏移量。
在本公开的一种示例性实施例中,所述目标位置通过以下步骤确定:从所述第三存储区域中查找偏移量最小的空闲位置,作为所述目标位置。
在本公开的一种示例性实施例中,在将所述值数据存储至第三存储区域的目标位置之前,所述方法还包括:如果检测到所述第三存储区域中存在与待存储的值数据相同的已存储的值数据,则将该已存储的值数据所在的位置的偏移量存储至所述目标值存储单元;如果检测到所述第三存储区域中不存在与待存储的值数据相同的已存储的值数据,则执行将所述待存储的值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元的步骤。
在本公开的一种示例性实施例中,所述方法还包括:当根据所述键数据或所述键数据的哈希值查找所述值数据时,在所述第一存储区域中查找所述键数据或所述键数据的哈希值所在的键存储单元,为所述目标键存储单元;在所述第二存储区域中查找与所述目标键存储单元具有关联的目标值存储单元;如果所述目标值存储单元存储的为值数据,则从所述目标值存储单元读取所述值数据;如果所述目标值存储单元存储的为偏移量,则根据所述偏移量,从所述第三存储区域中读取所述值数据。
根据本公开的一个方面,提供一种数据存储装置,包括:数据处理模块,用于对初始的多维数据进行扁平化处理,得到键值数据,所述键值数据包括成对的键数据和值数据;第一存储模块,用于将所述键数据或所述键数据的哈希值存储至第一存储区域的目标键存储单元;第二存储模块,用于确定所述值数据的长度未超过字节阈值,则将所述值数据存储至第二存储区域的目标值存储单元,所述目标值存储单元与所述目标键存储单元具有关联;第三存储模块,用于确定所述值数据的长度超过所述字节阈值,则将所述值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域。
在本公开的一种示例性实施例中,数据处理模块包括:初始字典获取单元,用于获取多个初始数据字典,所述初始数据字典中包括多维数据;中间字典获取单元,用于对所述多个初始数据字典中的所述多维数据分别进行扁平化处理,得到多个包括一维数据的中间数据字典;目标字典生成单元,用于将所述多个中间数据字典合并,生成目标数据字典,并将所述目标数据字典中的一维数据分别确定为所述键值数据。
在本公开的一种示例性实施例中,数据存储装置还包括:数据输出模块,用于在存储所述目标数据字典中的所有一维数据后,将已存储的键值数据输出为二进制数据文件。
在本公开的一种示例性实施例中,数据存储装置还包括:键存储确定单元,用于将所述第一存储区域的存储单元确定为键存储单元,所述目标键存储单元从所述键存储单元中确定;值存储确定单元,用于将所述第二存储区域划分为多个具有所述预设字节的值存储单元,所述目标值存储单元从所述值存储单元中确定。
在本公开的一种示例性实施例中,键存储单元包括:存储单元划分子单元,用于将所述第一存储区域划分为具有固定字节的所述键存储单元。
在本公开的一种示例性实施例中,第三存储模块包括:判断单元,用于确定所述值数据的长度超过所述字节阈值,则判断所述值数据是否满足数据嵌套规则;以及如果所述值数据满足所述数据嵌套规则,则将所述值数据存储至第三存储区域的目标位置;所述数据嵌套规则包括:所述值数据为嵌套数据时,所述嵌套数据的层数不超过两层;所述值数据为两层嵌套数据时,所述值数据仅可为整型数据或浮点型数据;以及所述值数据的数据元素的类型唯一。
在本公开的一种示例性实施例中,所述值数据的类型为Python数据类型,在存储所述值数据之前,将所述值数据转换为C或C++数据类型。
在本公开的一种示例性实施例中,第三存储模块包括:数据写入单元,用于将所述值数据的长度和所述值数据写入所述第三存储区域的目标位置;其中,所述值数据位于所述值数据的长度之后,所述目标位置的偏移量用于指示所述目标位置的起始位置,所述值数据的长度具有固定字节,所述偏移量、所述固定字节和所述值数据的长度之和用于指示所述目标位置的结束位置。
在本公开的一种示例性实施例中,数据存储装置还包括:数据转换模块,用于在得到所述键值数据之后,将所述键数据转换为无符号的整型数据,并计算所述整型数据的哈希值;哈希索引确定模块,用于采用求模式运算符与直接寻址确定所述哈希值的哈希索引;第一存储模块包括:哈希值写入单元,用于根据所述哈希索引在所述第一存储区域中确定所述目标键存储单元,将所述键数据的哈希值写入所述目标键存储单元。
在本公开的一种示例性实施例中,所述目标值存储单元通过以下步骤确定:将所述目标键存储单元的偏移量加上所述第一存储区域的长度,得到所述目标值存储单元的偏移量。
在本公开的一种示例性实施例中,所述目标位置通过以下步骤确定:从所述第三存储区域中查找偏移量最小的空闲位置,作为所述目标位置。
在本公开的一种示例性实施例中,数据存储装置还包括:检测模块,用于在将所述值数据存储至第三存储区域的目标位置之前,如果检测到所述第三存储区域中存在与待存储的值数据相同的已存储的值数据,则将该已存储的值数据所在的位置的偏移量存储至所述目标值存储单元;以及如果检测到所述第三存储区域中不存在与待存储的值数据相同的已存储的值数据,则执行将所述待存储的值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元的步骤。
在本公开的一种示例性实施例中,数据存储装置还包括:数据查找模块,用于当根据所述键数据或所述键数据的哈希值查找所述值数据时,在所述第一存储区域中查找所述键数据或所述键数据的哈希值所在的键存储单元,为所述目标键存储单元;在所述第二存储区域中查找与所述目标键存储单元具有关联的目标值存储单元;如果所述目标值存储单元存储的为值数据,则从所述目标值存储单元读取所述值数据;以及如果所述目标值存储单元存储的为偏移量,则根据所述偏移量,从所述第三存储区域中读取所述值数据。
根据本公开的一个方面,提供一种电子设备,包括:处理器;以及存储器,用于存储所述处理器的可执行指令;其中,所述处理器配置为经由执行所述可执行指令来执行上述任意一项所述的方法。
根据本公开的一个方面,提供一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现上述任意一项所述的方法。
本公开的示例性实施例具有以下有益效果:
对初始的多维数据进行扁平化处理,得到键值数据,键值数据包括成对的键数据和值数据,将键数据或键数据的哈希值存储至第一存储区域的目标键存储单元,确定值数据的长度未超过字节阈值,则将值数据存储至第二存储区域的目标值存储单元,目标值存储单元与目标键存储单元具有关联,确定值数据的长度超过字节阈值,则将值数据存储至第三存储区域的目标位置,并将目标位置的偏移量存储至目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域。一方面,对多维数据进行扁平化处理,可以得到成对的键值数据,使每一个值数据具有与其匹配的键数据,相比于使用复杂的字典结构中多维嵌套的数据格式,降低了数据存储的复杂度;另一方面,多维嵌套的数据在进行查找时,其过程需要进行多次查询,本示例性实施例通过键值数据的形式对数据进行存储,能够更快的查找到键数据对应的值数据,提高数据查询效率;再一方面,根据字节阈值数确定值数据的存储区域,并将超过字节阈值的值数据存储至第三存储区域,而将其在第三区域的目标位置的偏移量和未超过字节阈值的值数据存储至第二存储区域,使得数据存储更加具有规则性,避免了在存储数据时预留大量冗余的内存空间,造成的内存增加,进一步压缩了内存空间。
应当理解的是,以上的一般描述和后文的细节述仅是示例性和解释性的,并不能限制本公开。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理。显而易见地,下面描述中的附图仅仅是本公开的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1示意性示出本示例性实施例中一种数据存储方法的流程图;
图2示意性示出本示例性实施例中一种数据存储方法的子流程图;
图3示意性示出本示例性实施例中一种数据查询方法的流程图;
图4示意性示出本示例性实施例中一种数据存储装置的结构框图;
图5示意性示出本示例性实施例中一种用于实现上述方法的电子设备;
图6示意性示出本示例性实施例中一种用于实现上述方法的计算机可读存储介质。
具体实施方式
现在将参考附图更全面地描述示例实施方式。然而,示例实施方式能够以多种形式实施,且不应被理解为限于在此阐述的范例;相反,提供这些实施方式使得本公开将更加全面和完整,并将示例实施方式的构思全面地传达给本领域的技术人员。所描述的特征、结构或特性可以以任何合适的方式结合在一个或更多实施方式中。
本公开的示例性实施例首先提供一种数据存储方法,用于在内存中存储键值数据,以便于程序对其进行加载获取数据,或进行数据查找等。该方法的执行主体可以是服务器,也可以是终端设备。
下面结合附图1对本示例性实施例做进一步说明,如图1所示,数据存储方法可以包括以下步骤S110~S140:
步骤S110,对初始的多维数据进行扁平化处理,得到键值数据,键值数据包括成对的键数据和值数据。
通常在进行数据存储时,首先会获取一关于存储数据的初始表格,其可以是人工填写的excel表格,也可以是统计历史数据得到的表格等,例如,表1示出了一关于某一游戏活动的表格数据:
表1
活动编号 | 活动名称 | 活动介绍 | 等级要求 | 开启时间 | 结束时间 |
1 | 跑马灯活动 | 跑马灯活动来了 | 50 | 2019.2.3 | 2019.2.15 |
2 | 踏青节 | 踏青节开启了 | 10 | 2019.4.11 | 2019.4.25 |
为了将其进行存储,一般会采用特定的系统将表格转换为程序运行时可以加载进内存的内容格式,例如,以下示例性代码为将上述表1中的数据转换为Python字典结构的源码文件(程序脚本语言为Python时):
#-*-coding:utf-8-*-
data={
1:{‘name’:‘跑马灯活动’,‘description’:‘跑马灯活动来了’,‘join_level’:50,‘open_date’:‘2019.2.3’,‘close_date’:‘2019.2.15’},
2:{‘name’:‘踏青节’,‘description’:‘踏青节开启了’,‘join_level’:10,‘open_date’:‘2019.4.11’,‘close_date’:‘2019.4.25’},
}
其中,表格数据中可以包括多个元组数据,每一元组数据可以包括多个维度,为了对其进行存储,可以将其转换为源码文件,例如活动编号为1的元组中包括:活动名称、活动介绍、可参与玩家等级、开启时间、结束时间多个维度的数据,将其转换为源码文件时,对应代码为:1:{‘name’:‘跑马灯活动’,‘description’:‘跑马灯活动来了’,‘join_level’:50,‘open_date‘:‘2019.2.3’,‘close_date’:‘2019.2.15’},即本示例性实施例中初始的多维数据。
为了节省数据存储所占用的空间,使其拥有较低的内存占有率,本示例性实施例可以通过扁平化的处理方法,将初始的多维数据转化为多个一维数据,其中,对多维数据进行扁平化处理可以视为对多维数据进行降维的过程,使多维嵌套的每一个数据值能够分配与其对应的数据键,即通过扁平化处理,得到成对的键数据与值数据,举例说明:
对以下多维数据进行扁平化处理:
1:{‘name’:‘跑马灯活动’,‘description’:‘跑马灯活动来了’,‘join_level’:50,‘open_date‘:‘2019.2.3’,‘close_date’:‘2019.2.15’},
可以得到多个一维数据:
{1:‘name’}:‘跑马灯活动’,
{1:‘description’}:‘跑马灯活动来了’,
{1:‘join_level’}:50,
{1:‘open_date’}:‘2019.2.3’,
{1:‘close_date’}:‘2019.2.15’,
键值数据通常用以表示非关系型数据,通过具有唯一标识性的键数据,可以确定该键数据对应的值数据。在本示例性实施例中,得到的一维数据可以确定待存储的键值数据,例如上述一维数据中,“{1:‘name’}”可以作为键数据,“‘跑马灯活动’”可以作为值数据,其中键数据与值数据是成对的。本示例性实施例中,扁平化处理可以采用多种方式,例如递归算法、扩展运算符等,本公开对此不做具体限定。
在实际应用中,考虑到可能会出现需要将多个程序所需的数据表格中的数据进行存储的情况,因此,需要将这些数据表格进行合并。在一示例性实施例中,步骤S110中,对初始的多维数据进行扁平化处理,得到键值数据可以包括以下步骤:
步骤S210,获取多个初始数据字典,初始数据字典中包括多维数据;
步骤S220,对多个初始数据字典中的多维数据分别进行扁平化处理,得到多个包括一维数据的中间数据字典;
步骤S230,将多个中间数据字典合并,生成目标数据字典,并将目标数据字典中的一维数据分别确定为键值数据。
其中,数据字典是指对数据的数据项、数据结构、数据流、数据存储、处理逻辑等进行定义和描述,其可以通过特定的导表系统对数据表格进行加工处理得到。初始数据字典是指包含步骤S110中初始的多维数据的字典结构,中间数据字典是指包含将初始的多维数据进行扁平化处理后的一维数据的数据结构,目标数据字典是指将多个中间数据字典进行合并后得到的最终的字典结构,其可以被导出为特定文件,例如pickle文件。
目标数据字典的生成过程,以两个初始数据字典的源码文件shop.py与unit.py为例,
shop.py的源码文件如下:
unit.py的源码文件如下:
将shop.py与unit.py中的多维数据进行扁平化处理可以得到两个中间数据字典,将两个中间数据字典合并,可以得到目标数据字典,其源码文件如下:
步骤S120,将键数据或键数据的哈希值存储至第一存储区域的目标键存储单元。
其中,第一存储区域可以是指从内存中划分的一部分用于存储关于键数据的区域,第一存储区域可以由多个连续或不连续的内存单元组成,键数据所存储的单元即为目标键存储单元,在本示例性实施例中,在确定了键值数据与每个键存储单元的空间大小后,可以确定第一存储区域所占的内存大小。键数据写入第一存储区域的顺序,可以根据初始表格或源码文件确定,例如,
('shop',10041,'sample_field1'):1,
('shop',10041,'sample_field2'):'hello',
('shop',10042,'sample_field1'):2,
可以按照源码文件的代码顺序或数据生成顺序分别写入键数据('shop',10041,'sample_field1')、('shop',10041,'sample_field2')、('shop',10042,'sample_field1'),也可以根据键数据的类型确定,例如在上述键数据中,先写入关于“'sample_field1'”的键数据,可以按照('shop',10041,'sample_field1')、('shop',10042,'sample_field1')、('shop',10041,'sample_field2')的顺序写入第一存储区域等等,本公开对此不做具体限定。
步骤S130,如果确定值数据的长度未超过字节阈值,则将值数据存储至第二存储区域的目标值存储单元,目标值存储单元与目标键存储单元具有关联。
步骤S140,如果确定值数据的长度超过字节阈值,则将值数据存储至第三存储区域的目标位置,并将目标位置的偏移量存储至目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域。
在本示例性实施例中,为了合理分配值数据的存储单元,避免对所有数据存储时留出冗余空间,可以根据值数据的长度,将其存储至不同的存储区域。第二存储区域与第三存储区域均为用于存储键值数据中值数据的区域,其可以是从内存中划分的两部分具有特定大小的区域,第二存储区域与第三存储区域中均可以包括多个连续或不连续的内存单元,在第二存储区域中,值数据所存储的单元为目标值存储单元,在第三存储区域中,值数据可以存储于目标位置。另外,为了实现内存资源的最优化利用,本示例性实施例中,可以设置第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域。字节阈值可以是指用于判断值数据存储区域的判断条件,当值数据的长度未超过字节阈值,则可以将其存储于第二存储区域,第二存储区域中各存储单元的字节大小可以人为进行分配和设定,特别的,字节阈值的大小可以与目标值存储单元的字节大小相同,判断值数据存储于哪一存储区域,即为判断目标值存储单元的空间是否能够写入值数据;如果值数据的长度超过字节阈值,则可以认为值数据为不定长的块数据或其他较为复杂的数据,则可以将其存储至第三存储区域的目标位置。通过为第二存储区域设置字节阈值,将较长的值数据存储至第三存储区域,事先为部分符合长度要求的值数据在第二存储区域中划分存储空间,而在第三存储区域设置合理的预留空间用以存储较长或复杂的值数据,避免对所有数据预留空间造成的较短数据占用空间内存的问题,从而可以压缩数据的存储空间,优化数据存储逻辑。
在本示例性实施例中,为了更好的查询第三存储区域的值数据,可以将存储于第三存储区域的值数据的偏移量作为简单的值数据存储于第二存储区域中。其中,偏移量是指用于反映值数据存储于第三存储区域的哪一位置的数据,其可以是以第一存储区域为起点至第三存储区域中值数据所在目标位置的总字节数。
在一示例性实施例中,在存储目标数据字典中的所有一维数据后,可以将已存储的键值数据输出为二进制数据文件,使其他程序加载该二进制数据文件,以获取其中存储的键值数据。
在一示例性实施例中,值数据的类型可以为Python数据类型,在存储值数据之前,可以使用C++编写的特定工具程序加载目标数据字典导出的文件,将其中的值数据转化为C或C++类型的数据,即第二存储区域与第三存储区域存储的值数据的数据类型可以是C或C++的数据类型。
基于上述说明,在本示例性实施例中,对初始的多维数据进行扁平化处理,得到键值数据,键值数据包括成对的键数据和值数据,将键数据或键数据的哈希值存储至第一存储区域的目标键存储单元,确定值数据的长度未超过字节阈值,则将值数据存储至第二存储区域的目标值存储单元,目标值存储单元与目标键存储单元具有关联,确定值数据的长度超过字节阈值,则将值数据存储至第三存储区域的目标位置,并将目标位置的偏移量存储至目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域。一方面,对多维数据进行扁平化处理,可以得到成对的键值数据,使每一个值数据具有与其匹配的键数据,相比于使用复杂的字典结构中多维嵌套的数据格式,降低了数据存储的复杂度;另一方面,多维嵌套的数据在进行查找时,其过程需要进行多次查询,本示例性实施例通过键值数据的形式对数据进行存储,能够更快的查找到键数据对应的值数据,提高数据查询效率;再一方面,根据字节阈值数确定值数据的存储区域,并将超过字节阈值的值数据存储至第三存储区域,而将其在第三区域的目标位置的偏移量和未超过字节阈值的值数据存储至第二存储区域,使得数据存储更加具有规则性,避免了在存储数据时预留大量冗余的内存空间,造成的内存增加,进一步压缩了内存空间。
在一示例性实施例中,数据存储方法还可以包括以下步骤:
将第一存储区域的存储单元确定为键存储单元,目标键存储单元从键存储单元中确定;
将第二存储区域划分为多个具有预设字节的值存储单元,目标值存储单元从值存储单元中确定。
在本示例性实施例中,第一存储区域、第二存储区域和第三存储区域为内存中的三个子区域,其基本存储单元都是内存的内存单元,本质上是相同的,只是后续存放的数据类型不同,本示例性实施例将第一存储区域的存储单元称为键存储单元,用于存储键值数据的键数据,将第二存储区域和第三存储区域的存储单元称为值存储单元,用于存储键值数据的值数据。在本示例性实施例中,可以设置预设字节的字节数可以与步骤S130与步骤S140中的字节阈值相同,特别的,针对不同预设字节的值数据,本示例性实施例具有不同的存储单元,以更好的设计数据存储的空间。
根据实际应用需求,可以确定第一存储区域、第二存储区域与第三存储预期所需空间的比例关系,进而决定分别划分多少内存空间到三个区域。在划分时,以第一存储区域为例,可以从内存分出一段连续的内存单元形成第一存储区域,键存储区域和值存储区域同样也可以由连续的内存单元组成,本公开对此不做限定。对内存的划分可以具体包括以下几种具体实施方式:
(1)在内存中配置一张关于存储单元地址的列表,记录哪些存储单元属于第一存储区域,哪些属于第二存储区域,哪些属于第三存储区域。但是在未存储数据的情况下,三个区域之间不存在任何关联关系。
(2)通过指针配置第一存储区域、第二存储区域和第三存储区域的层级关系,例如:通过单向链表,将值存储单元链接到键存储单元,再将目标位置链接到值存储单元,从而在一维地址的基础上,配置了目标键存储单元、目标值存储单元以及目标位置之间的层级与关联关系,与上述划分方式(1)不同的是,在未存储数据的情况下,三个区域之间就已经存在关联关系。
(3)根据预设的第一存储区域、第二存储区域和第三存储区域的大小在内存中直接划分出连续的固定大小的区域,其中第一存储区域、第二存储区域与第三存储区域中的存储单元均为连续的,例如存储3对键值数据,设定目标键存储单元与目标值存储单元的字节长度为4个字节,并且为第三存储区域留出预设长度的存储空间,则在划分内存时,即可以确定第一存储区域与第二存储区域均需要12个字节,以及第三存储区域的预设长度的字节。
本示例性实施例中,无论采取哪种划分方式,在划分出第一存储区域后,可以向其中的每个存储单元分别写入不同的键数据或键数据的哈希值,从而确定上述目标键存储单元。
在一示例性实施例中,上述将第一存储区域的存储单元确定为键存储单元可以包括:将第一存储区域划分为具有固定字节的键存储单元。
在进行数据存储时,第一存储区域中的键存储单元可以设置为固定字节,例如4个字节,则三个键值数据需要进行存储时,存储三个键数据则需要12个字节。在本示例性实施例中,第二存储区域的值存储单元的预设字节也可以设置为4个字节。
在一示例性实施例中,将值数据存储至第三存储区域的目标位置可以包括:将值数据的长度和值数据写入第三存储区域的目标位置;
其中,值数据位于值数据的长度之后,目标位置的偏移量用于指示目标位置的起始位置,值数据的长度具有固定字节,偏移量、固定字节和值数据的长度之和用于指示目标位置的结束位置。
在本示例性实施例中,由于第三存储区域存储的值数据为长度较长且较为复杂的块数据,为了能够快速确定其存储的目标位置,合理划分存储内存空间,可以将值数据的长度写入第三存储区域的目标位置,其后可以连续写入值数据本身。例如写入值数据“‘helloworld’”时,可以写入11(2),‘hello world’(11),11则可以表示‘hello world’所占的字节长度,长度数据在第三存储区域所占的空间可以设置为固定字节,如两个字节,则根据存储长度11和其本身所占的字节数2,可以得到长度数据与值数据所占的字节总数为13个字节,能够更快的确定下一值数据的长度数据存储的位置,即能够准确获取值数据在第三存储区域存储的目标位置的偏移量,以将其写入第二存储区域。
举例说明,以下为一个shop表,其内容如下:
对其中的多维数据进行扁平化处理后,得到:
在对上述数据进行存储时,将会存储为如下表2所示(括号内为数据所占的字节数):
表2
在上述数据中,一共有3个键值对,第一存储区域中键存储单元部分一共占了12个字节,因此,第二存储区域的值存储单元也一共占用了12个字节,其中“'hello world'”与“(1.1,2.2)”超过第二存储区域中值存储单元的字节阈值,则将其偏移量存储至第二存储区域的值存储单元中。因此,第二存储区域中值存储单元分别为int32_t类型的600001001,Offset(偏移量)类型的24,Offset类型的37。其中Offset类型的24记录了从第一存储区域的起始位置算起,偏移24个字节后的位置,即第三存储区域的目标位置,也就是12+4+4+4,正好是存储了2个字节的11的位置,这里存储的11是其后面字符串的字节长度;Offset类型的37记录了从第一存储区域的起始位置算起,偏移37个字节后的位置,也就是12+4+4+4+2+11,正好是存储了2个字节的8的位置,这里存储的8是其后面长度2的float类型数组的字节长度。
在一示例性实施例中,步骤S130中,确定值数据的长度超过字节阈值,则将值数据存储至第三存储区域的目标位置可以包括以下步骤:
确定值数据的长度超过字节阈值,则判断值数据是否满足数据嵌套规则;
如果值数据满足数据嵌套规则,则将值数据存储至第三存储区域的目标位置;
上述数据嵌套规则包括:
(1)、值数据为嵌套数据时,嵌套数据的层数不超过两层;
(2)、值数据为两层嵌套数据时,值数据仅可为整型数据或浮点型数据;以及
(3)、值数据的数据元素的类型唯一。
为了高效、快速地存储键值数据,并且提高键值数据的查询效率,本示例性实施例对存储至第三存储区域的目标位置的值数据设置了数据嵌套规则。将长度较长、且满足数据嵌套规则的值数据存储至第三存储区域的目标位置,例如较为复杂且满足数据嵌套规则的块数据。
在本示例性实施例中,数据嵌套规则是指键值数据中的键数据同时满足上述(1)、(2)、(3)3种规则。其中,数据嵌套规则(1)可以避免由于深层的嵌套造成的数据对象构建时间较长,进而查询效率较低的问题。数据嵌套规则(2)和(3)可以使值数据的类型较为统一且简单,避免了花费额外的存储空间标记多种数据类型的问题。
举例说明,以下为满足数据嵌套规则的数据:
“string literal value”
(1,2,3,4,5)
(1.0,2.0,3.0,4.0,5.0)
(“str1”,“str2”,“str3”)
((1,2,3),(4,5,6))
((1.0,2.0,3.0),(4.0,5.0,6.0))
以下为不满足数据嵌套规则的数据:
(1,2.0,3,4.0,5)//,不满足上述数据嵌套规则(2),其中“1”和“2.0”属于不同的类型;
((“str1”,“str2”),(“str3”,))//,不满足上述数据嵌套规则(3),其中“str1”,“str2”,“str3”既不是整型数据,也不是浮点型数据;
(((1,2),(3,)),((4,5),(6,)))//,不满足上述数据嵌套规则(1),其中,数据的嵌套层数为3层;
((1.0,2,3.0),(4,5.0,6.0))//,不满足上述数据嵌套规则(2),包括的数据元素的类型并不唯一。
在一示例性实施例中,在得到键值数据之后,数据存储方法还可以包括以下步骤:
将键数据转换为无符号的整型数据,并计算整型数据的哈希值;
采用求模式运算符或直接寻址确定哈希值的哈希索引;
进一步的,步骤S120可以包括:
根据哈希索引在第一存储区域中确定目标键存储单元,将键数据的哈希值写入目标键存储单元。
通常,键数据可能会包含多种类型的数据,例如整型、浮点型或其他字符串类型,在本示例性实施例中,可以先将键数据转换为无符号的整型数据,例如uint_64,为了进一步减少键数据所占用的存储空间,还可以将uint_64压缩为uint_32。计算哈希值的具体操作可以是,针对键数据中的每个元素:当此元素为PyStringObject时,利用PyObjectHash(Python自带的Hash Function)计算出一个数值,而其他类型(如PyIntObject,PyFloatObject)则可以直接使用其本身的数值。将这些代表数值依次写入一小段连续内存中,提交给XXHash64(哈希算法库)可以计算出类型为uint64_t的哈希值,如果是将uint_64压缩为uint_32时,则可以计算出类型为uint_32的哈希值等等。为了在第一存储区域中确定目标键存储单元,可以通过求模运算符或直接寻址的方法确定上述哈希值的哈希索引,其中,索引可以存储对应的哈希值,哈希索引的结构十分紧凑,能够使得哈希表拥有较快的查询效率。在本示例性实施例中,哈希字典的load factor(载荷系数)高达0.85时,仍能保持较为高效的查询效率。另外,将键数据的哈希值存储至第一存储区域的目标键存储单元,使数据在存储时不再依赖Python的字典结构,避免了哈希冲突预留冗余空间的问题,且无需存储大量冗余指针,减少了数据存储所需的内存空间,进一步实现了对内存的压缩。
在一示例性实施例中,目标值存储单元可以通过以下步骤确定:
将目标键存储单元的偏移量加上第一存储区域的长度,得到目标值存储单元的偏移量。
在本示例性实施例中,键值数据中的值数据在写入第二存储区域中时可以按顺序写入,为了使目标键存储单元与目标值存储单元具有一定的关联关系,以便于确定目标键存储单元时,能够查找到目标值存储单元所存储的值数据,本示例性实施例中目标值存储单元的偏移量,可以根据目标键存储单元的偏移量加上第一存储区域的长度确定。例如,第一存储区域的长度为12个字节,目标键存储单元的偏移量为4个字节,确定目标值存储单元的偏移量为16个字节,换而言之,当以第二存储区域为偏移起点时,目标值存储单元的偏移量也为4个字节,即键数据存储于第一存储区域的第几个目标键存储单元中,值数据也将存储于第二存储区域的第几个目标值存储单元中,本示例性实施例通过目标键存储单元的偏移量以及第一存储区域的长度确定目标值存储单元的偏移量,建立目标键存储单元与目标值存储单元的对应关系,可以便于值数据的查找。
在一示例性实施例中,目标位是可以通过以下步骤确定:
从第三存储区域中查找偏移量最小的空闲位置,作为目标位置。
可以认为,值数据在写入第三存储区域时,是按顺序依次写入的,偏移量是指空闲位置的偏移量,即查找第三存储区域中哪一位置还没有被写入值数据,则将该空闲位置作为目标位置。本示例性实施例可以充分利用空间进行数据存储,避免了预留多余的空间额外占用的存储资源。
在一示例性实施例中,在将键数据存储至第三存储区域的目标位置之间,数据存储方法还可以包括以下步骤:
如果检测到第三存储区域中存在与待存储的值数据相同的已存储的值数据,则将该已存储的值数据所在的位置的偏移量存储至目标值存储单元;
如果检测到第三存储区域中不存在与待存储的值数据相同的已存储的值数据,则执行将待存储的值数据存储至第三存储区域的目标位置,并将目标位置的偏移量存储至目标值存储单元的步骤。
在本示例性实施例中,存储至第三存储区域的值数据通常为较复杂,字节数较长的值数据,如数据块。在实际的存储过程中,可能会出现相同的值数据的情况,第三存储区域中第一次出现的值数据在第二存储区域中存在一对应的偏移量,为了进一步压缩存储空间,本示例性实施例中,当检测到第三存储区域中存在与待存储的值数据相同的已存储的值数据时,可以无需再次将该值数据存储至第三存储区域,可以仅将已存储的值数据所在的位置的偏移量存储至目标值存储单元即可,可以认为第二存储区域中可以存在多个相同的偏移量,指示其值数据具体为第三存储区域的同一值数据,由于这种同值优化是跨表、全局的,其对数据压缩的性能贡献十分巨大。
在一示例性实施例中,数据存储方法还可以包括以下步骤:
步骤S310,当根据键数据或键数据的哈希值查找值数据时,在第一存储区域中查找键数据或键数据的哈希值所在的键存储单元,为目标键存储单元;
步骤S320,在第二存储单元中查找与目标键存储单元具有关联的目标值存储单元;
步骤S330,如果目标值存储单元存储的为值数据,则从目标值存储单元读取值数据;
步骤S340,如果目标值存储单元存储的为偏移量,则根据偏移量,从第三存储区域中读取值数据。
在本示例性实施例中,目标键存储单元与目标值存储单元具有关联关系,其可以是通过目标键存储单元中的哈希值确定目标值存储单元,也可以是目标键存储单元与目标值存储单元具有映射关系,例如第一个目标键存储单元对应第一个目标值存储单元等等。当根据键数据或键数据的哈希值查找值数据时,可以先确定第一存储区域中键数据或键数据的哈希值所在的目标键存储单元,进而确定与其对应的第二存储区域的目标值存储单元,读取该目标值存储单元中的数据,如果该数据为值数据本身,则可以直接从目标值存储单元中读取该数据作为值数据,如果该数据为偏移量,则需要根据偏移量在第三存储区域的目标位置中确定值数据。本示例性实施例可以使数据在存储时,在内存中展开排列,以便在进行数据查询时,可以被线性获取。
本示例性实施例相比与普通的Pyhon字典结构的存储方法,拥有更高的加载速度与更小的内存占有率,以下为本示例性实施例方法构建的字典结构BufferedDict与通过的Pyhon字典结构的存储方法对比的测试结果。
其中,表3示出了关于加载速度的测试结果,特别的,在本示例性实施例中表格数据越多,其优化程度越高。
表3
Python字典 | BufferedDict | 优化占比 |
1.23s | 0.007s | 0.57% |
表4示出了内存占有的测试结果:
表4
Python字典内存占用 | BufferedDict | 优化占比 |
26.6M | 4.06M | 15.3% |
表5示出了查询耗时的测试结果:
表5
如上表所示,由于BufferedDict摒弃了多维嵌套字典,使用了扁平化后的键值对形式,对于Python多维嵌套字典来说,从表名开始,经过行id,最终到列名的查询需要三次字典查询,而BufferedDict仅需一次字典查询,效率是优于使用Python字典的。
本公开的示例性实施例还提供了一种数据存储装置。参照图4,该装置400可以包括:数据处理模块410,用于对初始的多维数据进行扁平化处理,得到键值数据,键值数据包括成对的键数据和值数据;第一存储模块420,用于将键数据或键数据的哈希值存储至第一存储区域的目标键存储单元;第二存储模块430,用于确定值数据的长度未超过字节阈值,则将值数据存储至第二存储区域的目标值存储单元,目标值存储单元与目标键存储单元具有关联;第三存储模块440,用于确定值数据的长度超过字节阈值,则将值数据存储至第三存储区域的目标位置,并将目标位置的偏移量存储至目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域。
在一示例性实施例中,数据处理模块可以包括:初始字典获取单元,用于获取多个初始数据字典,初始数据字典中包括多维数据;中间字典获取单元,用于对所述多个初始数据字典中的多维数据分别进行扁平化处理,得到多个包括一维数据的中间数据字典;目标字典生成单元,用于将所述多个中间数据字典合并,生成目标数据字典,并将目标数据字典中的一维数据分别确定为键值数据。
在一示例性实施例中,数据存储装置还可以包括:数据输出模块,用于在存储目标数据字典中的所有一维数据后,将已存储的键值数据输出为二进制数据文件。
在一示例性实施例中,数据存储装置还可以包括:键存储确定单元,用于将第一存储区域的存储单元确定为键存储单元,目标键存储单元从键存储单元中确定;值存储确定单元,用于将第二存储区域划分为多个具有预设字节的值存储单元,目标值存储单元从值存储单元中确定。
在一示例性实施例中,键存储单元可以包括:存储单元划分子单元,用于将第一存储区域划分为具有固定字节的键存储单元。
在一示例性实施例中,第三存储模块可以包括:判断单元,用于确定值数据的长度超过字节阈值,则判断值数据是否满足数据嵌套规则;以及如果值数据满足数据嵌套规则,则将值数据存储至第三存储区域的目标位置;数据嵌套规则包括:值数据为嵌套数据时,嵌套数据的层数不超过两层;所述值数据为两层嵌套数据时,所述值数据仅可为整型数据或浮点型数据;以及所述值数据的数据元素的类型唯一。
在一示例性实施例中,值数据的类型为Python数据类型,在存储值数据之前,将值数据转换为C或C++数据类型。
在一示例性实施例中,第三存储模块可以包括:数据写入单元,用于将值数据的长度和值数据写入第三存储区域的目标位置;其中,值数据位于值数据的长度之后,目标位置的偏移量用于指示目标位置的起始位置,值数据的长度具有固定字节,偏移量、固定字节和值数据的长度之和用于指示目标位置的结束位置。
在一示例性实施例中,数据存储装置还可以包括:数据转换模块,用于在得到键值数据之后,将键数据转换为无符号的整型数据,并计算整型数据的哈希值;哈希索引确定模块,用于采用求模式运算符与直接寻址确定哈希值的哈希索引;第一存储模块包括:哈希值写入单元,用于根据哈希索引在第一存储区域中确定目标键存储单元,将键数据的哈希值写入目标键存储单元。
在一示例性实施例中,目标值存储单元可以通过以下步骤确定:将目标键存储单元的偏移量加上第一存储区域的长度,得到目标值存储单元的偏移量。
在一示例性实施例中,目标位置可以通过以下步骤确定:从第三存储区域中查找偏移量最小的空闲位置,作为目标位置。
在一示例性实施例中,数据存储装置还可以包括:检测模块,用于在将值数据存储至第三存储区域的目标位置之前,如果检测到第三存储区域中存在与待存储的值数据相同的已存储的值数据,则将该已存储的值数据所在的位置的偏移量存储至目标值存储单元;以及如果检测到第三存储区域中不存在与待存储的值数据相同的已存储的值数据,则执行将待存储的值数据存储至第三存储区域的目标位置,并将目标位置的偏移量存储至目标值存储单元的步骤。
在一示例性实施例中,数据存储装置还可以包括:数据查找模块,用于当根据键数据或键数据的哈希值查找值数据时,在第一存储区域中查找键数据或键数据的哈希值所在的键存储单元,为目标键存储单元;在第二存储区域中查找与目标键存储单元具有关联的目标值存储单元;如果目标值存储单元存储的为值数据,则从目标值存储单元读取值数据;以及如果目标值存储单元存储的为偏移量,则根据偏移量,从第三存储区域中读取值数据。
上述装置中各模块/单元的具体细节在方法部分的实施例中已经详细说明,未披露的细节内容可以参见方法部分的实施例内容,因此此处不再赘述。
本公开的示例性实施例还提供了一种能够实现上述方法的电子设备。
所属技术领域的技术人员能够理解,本公开的各个方面可以实现为系统、方法或程序产品。因此,本公开的各个方面可以具体实现为以下形式,即:完全的硬件实施方式、完全的软件实施方式(包括固件、微代码等),或硬件和软件方面结合的实施方式,这里可以统称为“电路”、“模块”或“系统”。
下面参照图5来描述根据本公开的这种示例性实施例的电子设备500。图5显示的电子设备500仅仅是一个示例,不应对本公开实施例的功能和使用范围带来任何限制。
如图5所示,电子设备500以通用计算设备的形式表现。电子设备500的组件可以包括但不限于:上述至少一个处理单元510、上述至少一个存储单元520、连接不同系统组件(包括存储单元520和处理单元510)的总线530、显示单元540。
其中,存储单元存储有程序代码,程序代码可以被处理单元510执行,使得处理单元510执行本说明书上述“示例性方法”部分中描述的根据本公开各种示例性实施方式的步骤。例如,处理单元510可以执行图1所示的步骤S110~S140,也可以执行图2所示的步骤S210~S230等。
存储单元520可以包括易失性存储单元形式的可读介质,例如随机存取存储单元(RAM)521和/或高速缓存存储单元522,还可以进一步包括只读存储单元(ROM)523。
存储单元520还可以包括具有一组(至少一个)程序模块525的程序/实用工具524,这样的程序模块525包括但不限于:操作系统、一个或者多个应用程序、其它程序模块以及程序数据,这些示例中的每一个或某种组合中可能包括网络环境的实现。
总线530可以为表示几类总线结构中的一种或多种,包括存储单元总线或者存储单元控制器、外围总线、图形加速端口、处理单元或者使用多种总线结构中的任意总线结构的局域总线。
电子设备500也可以与一个或多个外部设备700(例如键盘、指向设备、蓝牙设备等)通信,还可与一个或者多个使得用户能与该电子设备500交互的设备通信,和/或与使得该电子设备500能与一个或多个其它计算设备进行通信的任何设备(例如路由器、调制解调器等等)通信。这种通信可以通过输入/输出(I/O)接口550进行。并且,电子设备500还可以通过网络适配器560与一个或者多个网络(例如局域网(LAN),广域网(WAN)和/或公共网络,例如因特网)通信。如图所示,网络适配器560通过总线530与电子设备500的其它模块通信。应当明白,尽管图中未示出,可以结合电子设备500使用其它硬件和/或软件模块,包括但不限于:微代码、设备驱动器、冗余处理单元、外部磁盘驱动阵列、RAID系统、磁带驱动器以及数据备份存储系统等。
通过以上的实施方式的描述,本领域的技术人员易于理解,这里描述的示例实施方式可以通过软件实现,也可以通过软件结合必要的硬件的方式来实现。因此,根据本公开实施方式的技术方案可以以软件产品的形式体现出来,该软件产品可以存储在一个非易失性存储介质(可以是CD-ROM,U盘,移动硬盘等)中或网络上,包括若干指令以使得一台计算设备(可以是个人计算机、服务器、终端装置、或者网络设备等)执行根据本公开示例性实施例的方法。
本公开的示例性实施例还提供了一种计算机可读存储介质,其上存储有能够实现本说明书上述方法的程序产品。在一些可能的实施方式中,本公开的各个方面还可以实现为一种程序产品的形式,其包括程序代码,当程序产品在终端设备上运行时,程序代码用于使终端设备执行本说明书上述“示例性方法”部分中描述的根据本公开各种示例性实施方式的步骤。
参考图6所示,描述了根据本公开的示例性实施例的用于实现上述方法的程序产品600,其可以采用便携式紧凑盘只读存储器(CD-ROM)并包括程序代码,并可以在终端设备,例如个人电脑上运行。然而,本公开的程序产品不限于此,在本文件中,可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行系统、装置或者器件使用或者与其结合使用。
程序产品可以采用一个或多个可读介质的任意组合。可读介质可以是可读信号介质或者可读存储介质。可读存储介质例如可以为但不限于电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。
计算机可读信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了可读程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或上述的任意合适的组合。可读信号介质还可以是可读存储介质以外的任何可读介质,该可读介质可以发送、传播或者传输用于由指令执行系统、装置或者器件使用或者与其结合使用的程序。
可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于无线、有线、光缆、RF等等,或者上述的任意合适的组合。
可以以一种或多种程序设计语言的任意组合来编写用于执行本公开操作的程序代码,程序设计语言包括面向对象的程序设计语言—诸如Java、C++等,还包括常规的过程式程序设计语言—诸如“C”语言或类似的程序设计语言。程序代码可以完全地在用户计算设备上执行、部分地在用户设备上执行、作为一个独立的软件包执行、部分在用户计算设备上部分在远程计算设备上执行、或者完全在远程计算设备或服务器上执行。在涉及远程计算设备的情形中,远程计算设备可以通过任意种类的网络,包括局域网(LAN)或广域网(WAN),连接到用户计算设备,或者,可以连接到外部计算设备(例如利用因特网服务提供商来通过因特网连接)。
此外,上述附图仅是根据本公开示例性实施例的方法所包括的处理的示意性说明,而不是限制目的。易于理解,上述附图所示的处理并不表明或限制这些处理的时间顺序。另外,也易于理解,这些处理可以是例如在多个模块中同步或异步执行的。
应当注意,尽管在上文详细描述中提及了用于动作执行的设备的若干模块或者单元,但是这种划分并非强制性的。实际上,根据本公开的示例性实施例,上文描述的两个或更多模块或者单元的特征和功能可以在一个模块或者单元中具体化。反之,上文描述的一个模块或者单元的特征和功能可以进一步划分为由多个模块或者单元来具体化。
本领域技术人员在考虑说明书及实践这里公开的发明后,将容易想到本公开的其他实施例。本申请旨在涵盖本公开的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本公开的一般性原理并包括本公开未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施例仅被视为示例性的,本公开的真正范围和精神由权利要求指出。
应当理解的是,本公开并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本公开的范围仅由所附的权利要求来限。
Claims (15)
1.一种数据存储方法,其特征在于,包括:
对初始的多维数据进行扁平化处理,得到键值数据,所述键值数据包括成对的键数据和值数据;
将所述键数据或所述键数据的哈希值存储至第一存储区域的目标键存储单元;
确定所述值数据的长度未超过字节阈值,则将所述值数据存储至第二存储区域的目标值存储单元,所述目标值存储单元与所述目标键存储单元具有关联;
确定所述值数据的长度超过所述字节阈值,则将所述值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域;
所述对初始的多维数据进行扁平化处理,得到键值数据,包括:
获取多个初始数据字典,所述初始数据字典中包括多维数据;
对所述多个初始数据字典中的所述多维数据分别进行扁平化处理,得到多个包括一维数据的中间数据字典;
将所述多个中间数据字典合并,生成目标数据字典,并将所述目标数据字典中的一维数据分别确定为所述键值数据。
2.根据权利要求1所述的方法,其特征在于,所述方法还包括:
在存储所述目标数据字典中的所有一维数据后,将已存储的键值数据输出为二进制数据文件。
3.根据权利要求1所述的方法,其特征在于,所述方法还包括:
将所述第一存储区域的存储单元确定为键存储单元,所述目标键存储单元从所述键存储单元中确定;
将所述第二存储区域划分为多个具有预设字节的值存储单元,所述目标值存储单元从所述值存储单元中确定。
4.根据权利要求3所述的方法,其特征在于,所述将所述第一存储区域的存储单元确定为键存储单元,包括:
将所述第一存储区域划分为具有固定字节的所述键存储单元。
5.根据权利要求1所述的方法,其特征在于,所述确定所述值数据的长度超过所述字节阈值,则将所述值数据存储至第三存储区域的目标位置,包括:
确定所述值数据的长度超过所述字节阈值,则判断所述值数据是否满足数据嵌套规则;
如果所述值数据满足所述数据嵌套规则,则将所述值数据存储至第三存储区域的目标位置;
所述数据嵌套规则包括:
所述值数据为嵌套数据时,所述嵌套数据的层数不超过两层;
所述值数据为两层嵌套数据时,所述值数据仅可为整型数据或浮点型数据;以及
所述值数据的数据元素的类型唯一。
6.根据权利要求1所述的方法,其特征在于,所述值数据的类型为Python数据类型,在存储所述值数据之前,将所述值数据转换为C或C++数据类型。
7.根据权利要求1所述的方法,其特征在于,所述将所述值数据存储至第三存储区域的目标位置,包括:
将所述值数据的长度和所述值数据写入所述第三存储区域的目标位置;
其中,所述值数据位于所述值数据的长度之后,所述目标位置的偏移量用于指示所述目标位置的起始位置,所述值数据的长度具有固定字节,所述偏移量、所述固定字节和所述值数据的长度之和用于指示所述目标位置的结束位置。
8.根据权利要求1所述的方法,其特征在于,在得到所述键值数据之后,所述方法还包括:
将所述键数据转换为无符号的整型数据,并计算所述整型数据的哈希值;
采用求模式运算符与直接寻址确定所述哈希值的哈希索引;
所述将所述键数据或所述键数据的哈希值存储至第一存储区域的目标键存储单元,包括:
根据所述哈希索引在所述第一存储区域中确定所述目标键存储单元,将所述键数据的哈希值写入所述目标键存储单元。
9.根据权利要求1所述的方法,其特征在于,所述目标值存储单元通过以下步骤确定:
将所述目标键存储单元的偏移量加上所述第一存储区域的长度,得到所述目标值存储单元的偏移量。
10.根据权利要求1所述的方法,其特征在于,所述目标位置通过以下步骤确定:
从所述第三存储区域中查找偏移量最小的空闲位置,作为所述目标位置。
11.根据权利要求1所述的方法,其特征在于,在将所述值数据存储至第三存储区域的目标位置之前,所述方法还包括:
如果检测到所述第三存储区域中存在与待存储的值数据相同的已存储的值数据,则将该已存储的值数据所在的位置的偏移量存储至所述目标值存储单元;
如果检测到所述第三存储区域中不存在与待存储的值数据相同的已存储的值数据,则执行将所述待存储的值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元的步骤。
12.根据权利要求1所述的方法,其特征在于,所述方法还包括:
当根据所述键数据或所述键数据的哈希值查找所述值数据时,在所述第一存储区域中查找所述键数据或所述键数据的哈希值所在的键存储单元,为所述目标键存储单元;
在所述第二存储区域中查找与所述目标键存储单元具有关联的目标值存储单元;
如果所述目标值存储单元存储的为值数据,则从所述目标值存储单元读取所述值数据;
如果所述目标值存储单元存储的为偏移量,则根据所述偏移量,从所述第三存储区域中读取所述值数据。
13.一种数据存储装置,其特征在于,包括:
数据处理模块,用于对初始的多维数据进行扁平化处理,得到键值数据,所述键值数据包括成对的键数据和值数据;
第一存储模块,用于将所述键数据或所述键数据的哈希值存储至第一存储区域的目标键存储单元;
第二存储模块,用于确定所述值数据的长度未超过字节阈值,则将所述值数据存储至第二存储区域的目标值存储单元,所述目标值存储单元与所述目标键存储单元具有关联;
第三存储模块,用于确定所述值数据的长度超过所述字节阈值,则将所述值数据存储至第三存储区域的目标位置,并将所述目标位置的偏移量存储至所述目标值存储单元,其中,所述第一存储区域、第二存储区域和第三存储区域为连续的内存存储区域;
数据处理模块被配置为:
获取多个初始数据字典,所述初始数据字典中包括多维数据;对所述多个初始数据字典中的所述多维数据分别进行扁平化处理,得到多个包括一维数据的中间数据字典;将所述多个中间数据字典合并,生成目标数据字典,并将所述目标数据字典中的一维数据分别确定为所述键值数据。
14.一种电子设备,其特征在于,包括:
处理器;以及
存储器,用于存储所述处理器的可执行指令;
其中,所述处理器配置为经由执行所述可执行指令来执行权利要求1-12任一项所述的方法。
15.一种计算机可读存储介质,其上存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现权利要求1-12任一项所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910667581.7A CN110399104B (zh) | 2019-07-23 | 2019-07-23 | 数据存储方法、数据存储装置、电子设备、存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910667581.7A CN110399104B (zh) | 2019-07-23 | 2019-07-23 | 数据存储方法、数据存储装置、电子设备、存储介质 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN110399104A CN110399104A (zh) | 2019-11-01 |
CN110399104B true CN110399104B (zh) | 2023-06-09 |
Family
ID=68325814
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201910667581.7A Active CN110399104B (zh) | 2019-07-23 | 2019-07-23 | 数据存储方法、数据存储装置、电子设备、存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN110399104B (zh) |
Families Citing this family (12)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111026748B (zh) * | 2019-11-05 | 2020-11-17 | 广州市玄武无线科技股份有限公司 | 网络访问频次管控的数据压缩方法、装置及系统 |
CN110941730B (zh) * | 2019-11-29 | 2020-12-08 | 南京甄视智能科技有限公司 | 基于人脸特征数据偏移的检索方法与装置 |
CN111209741B (zh) * | 2020-01-16 | 2023-09-26 | 网易(杭州)网络有限公司 | 表格数据字典的处理方法及装置 |
CN111274245B (zh) * | 2020-01-17 | 2022-07-12 | 苏州浪潮智能科技有限公司 | 一种用于优化数据存储的方法和装置 |
CN111405040B (zh) * | 2020-03-16 | 2021-05-07 | 北京星际荣耀空间科技股份有限公司 | 一种实时数据处理方法、装置及设备 |
CN111881317B (zh) * | 2020-07-31 | 2021-08-20 | 北京达佳互联信息技术有限公司 | 基于键值系统的数据存储方法、装置、电子设备及介质 |
CN112328636A (zh) * | 2020-10-27 | 2021-02-05 | 上海金仕达软件科技有限公司 | 一种数据查找方法、装置及电子设备 |
CN113190759A (zh) * | 2021-05-21 | 2021-07-30 | 上海微盟企业发展有限公司 | 一种网页生成方法、装置、设备及计算机可读存储介质 |
CN113486026A (zh) * | 2021-08-02 | 2021-10-08 | 北京字节跳动网络技术有限公司 | 数据处理方法、装置、设备及介质 |
CN114741456A (zh) * | 2022-04-14 | 2022-07-12 | 北京字节跳动网络技术有限公司 | 一种信息存储方法及装置 |
CN117785018A (zh) * | 2022-09-22 | 2024-03-29 | 超聚变数字技术有限公司 | 键值存储方法及系统 |
CN117149100B (zh) * | 2023-11-01 | 2024-04-23 | 恒生电子股份有限公司 | 数据存储方法及装置 |
Family Cites Families (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US10275229B2 (en) * | 2015-12-16 | 2019-04-30 | Sap Se | Encoded data object notation persistence format |
CN106202548B (zh) * | 2016-07-25 | 2018-09-04 | 网易(杭州)网络有限公司 | 数据存储方法、查找方法及装置 |
CN107943927B (zh) * | 2017-11-21 | 2018-10-16 | 清华大学 | 一种分布式存储系统中多维数据的存储模式转换方法 |
CN109460406B (zh) * | 2018-10-15 | 2021-03-23 | 咪咕文化科技有限公司 | 一种数据处理方法及装置 |
-
2019
- 2019-07-23 CN CN201910667581.7A patent/CN110399104B/zh active Active
Also Published As
Publication number | Publication date |
---|---|
CN110399104A (zh) | 2019-11-01 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110399104B (zh) | 数据存储方法、数据存储装置、电子设备、存储介质 | |
US9020910B2 (en) | Storing tables in a database system | |
US9235651B2 (en) | Data retrieval apparatus, data storage method and data retrieval method | |
EP3432157B1 (en) | Data table joining mode processing method and apparatus | |
CN111966649B (zh) | 一种高效去重的轻量级在线文件存储方法及装置 | |
CN112287182A (zh) | 图数据存储、处理方法、装置及计算机存储介质 | |
CN108197324B (zh) | 用于存储数据的方法和装置 | |
CN111817722A (zh) | 数据压缩方法、装置及计算机设备 | |
CN111414527B (zh) | 相似项目的查询方法、装置及存储介质 | |
US7672925B2 (en) | Accelerating queries using temporary enumeration representation | |
US8321429B2 (en) | Accelerating queries using secondary semantic column enumeration | |
CN110309184B (zh) | 一种航空运价数据的缓存方法及系统 | |
CN113867710A (zh) | 代码补全的方法和装置 | |
CN111767280A (zh) | 数据处理方法、装置及存储介质 | |
CN107832341B (zh) | Agnss用户去重统计方法 | |
CN110674086A (zh) | 数据合并方法、装置、电子设备及存储介质 | |
CN112199577B (zh) | 一种数据查询方法、装置及电子设备 | |
CN114168581A (zh) | 数据清洗方法、装置、计算机设备及存储介质 | |
CN110851452B (zh) | 数据表连接处理方法及装置、电子设备和存储介质 | |
CN114817657A (zh) | 待检索数据处理方法、数据检索方法、电子设备及介质 | |
CN114238334A (zh) | 异构数据编码、解码方法和装置、计算机设备和存储介质 | |
CN113076197A (zh) | 负载均衡方法及装置、存储介质及电子设备 | |
CN113407576A (zh) | 基于降维算法的数据关联方法及系统 | |
CN112015791A (zh) | 数据处理方法、装置、电子设备及计算机存储介质 | |
CN116567350B (zh) | 全景视频数据处理方法及系统 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |