一种异构数据存储与检索方法、装置、设备及存储介质与流程

文档序号:26361041发布日期:2021-08-20 20:37阅读:258来源:国知局
一种异构数据存储与检索方法、装置、设备及存储介质与流程

本申请涉及大数据技术,尤其涉及一种异构数据存储与检索方法、装置、设备及存储介质。



背景技术:

在某些场景下,如针对课程类数据的存储,是需要使用数据库(如mysql)异构存储并支持事务。课程类数据至少包括直播课程、点播课程、图文课程、付费课程等,它们拥有相同的状态机(如未提交、未上架、已下架、待审核、已驳回、审核通过等状态),也可以拥有各自独有的属性,如点播课程可能有视频相关的属性,付费课程可能有价格相关的属性。随着业务的发展,属性也会经常发生变化,甚至可能增加一种新的类型(如线下课程)。对于这种突发性变化,现有中存在一种基于数据库解决异构数据存储的方案。

具体的,通过实体-属性-值(entity-attribute-value,eav)数据库模型将模型的属性以记录的形式存放在数据表中,即使需要新增和移除属性,仅仅需要删除数据表中响应的记录即可,无需修改数据库结构。

然而,在eav模型中,因为一个实体类型的每个属性单独占用一行,所以数据的增长非常快,假如一种实体类型具有10个属性,传统模型方式占用100万行数据话,eav模型则需占用约1000万行,即使用eav模型进行异构数据存储时产生大量的行数据。



技术实现要素:

为解决上述技术问题,本申请期望提供一种异构数据存储与检索方法、装置、设备及存储介质。

本申请的技术方案是这样实现的:

第一方面,提供了一种数据存储方法,该方法包括:

获取包括m个属性的待存储数据;其中,m为正整数;

根据m个属性的属性特征对m个属性进行分类,得到属性特征为系统属性的第一类数据,以及属性特征为非系统属性的第二类数据;

将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区。

上述方案中,所述待存储数据中每个属性包括第一属性标识和属性值;所述方法还包括:获取所述待存储数据对应的元数据;其中,所述元数据包括自定义属性信息,所述自定义属性信息包括:自定义属性特征及其对应的属性集合,所述属性集合中包括至少一个属性的第二属性标识;利用目标属性的第一属性标识以及第一属性标识和第二属性标识的映射关系,将所述元数据中对应的自定义属性特征作为所述目标属性的属性特征。

上述方案中,所述将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区,包括:利用所述映射关系,确定每个属性的第一属性标识对应的第二属性标识;将所述第一类数据中每个属性的第二属性标识作为key,属性值作为value,存储至所述第一存储分区;将所述第二类数据中每个属性的第二属性标识作为key,属性值作为value,存储至所述第二存储分区。

上述方案中,所述自定义属性特征包括系统属性特征和多种非系统属性特征,所述第二存储分区包括多个第二子存储分区;所述将所述第二类数据存储至第二存储分区,包括:对所述第二类数据进行非系统属性分类,得到至少两种第三类数据;根据第三类数据的非系统属性类型,将所述第三类数据存储至对应的第二子存储分区。

上述方案中,所述自定义属性信息还包括自定义属性特征对应的分区标识;所述方法还包括:根据所述第一类数据的系统属性特征,在所述元数据中确定第一分区标识;根据所述第三类数据的非系统属性特征,在所述元数据中确定第二分区标识;所述将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区,包括:根据所述第一分区标识,将所述第一类数据存储到对应的第一存储分区;根据所述第二分区标识,将所述第三类数据存储到对应的第二子存储分区。

第二方面,提供了一种数据检索方法,应用于全文搜索引擎,其特征在于,所述方法包括:获取检索信息;根据所述检索信息确定n个第一属性标识;其中,n为正整数;根据所述n个第一属性标识查找存储分区,获取对应的n段检索数据;其中,所述存储分区是按照属性特征对属性进行分区存储;按照预设聚合策略对所述n段检索数据进行聚合,得到所述检索信息对应的检索结果。

上述方案中,所述根据所述n个第一属性标识查找存储分区,获取对应的n段检索数据,包括:基于预先设定的每个第一属性标识与对应的第二属性标识的映射关系,确定所述n个第一属性标识的n个第二属性标识;基于所述n个第二属性标识查找存储分区,获取所述n段检索数据。

上述方案中,所述按照预设聚合策略对所述n段检索数据进行聚合,得到所述检索信息对应的检索结果,包括:按照所述n个第一属性标识的排列顺序,对所述n段检索数据进行聚合,得到所述检索结果。

第三方面,提供了一种数据存储装置,该装置包括:

第一获取单元,用于获取包括m个属性的待存储数据;其中,m为正整数;

分类单元,用于根据m个属性的属性特征对m个属性对进行分类,得到属性特征为系统属性的第一类数据,以及属性特征为非系统属性的第二类数据;

存储单元,用于将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区。

第四方面,提供了一种数据检索装置,应用于全文搜索引擎,该装置包括:

第二获取单元,获取检索信息;

确定单元,用于根据所述检索信息确定n个第一属性标识;其中,n为正整数;

查找单元,根据所述n个第一属性标识查找存储分区,获取对应的n段检索数据;其中,所述存储分区是按照属性特征对属性进行分区存储;

聚合单元,按照预设聚合策略对所述n段检索数据进行聚合,得到所述检索信息对应的检索结果。

第五方面,提供了一种数据存储设备,包括:处理器和配置为存储能够在处理器上运行的计算机程序的存储器,其中,所述处理器配置为运行所述计算机程序时,执行前述方法的步骤。

第六方面,提供了一种全文搜索引擎,包括:处理器和配置为存储能够在处理器上运行的计算机程序的存储器,其中,所述处理器配置为运行所述计算机程序时,执行前述方法的步骤。

第七方面,提供了一种计算机可读存储介质,其上存储有计算机程序,其中,该计算机程序被处理器执行时实现前述方法的步骤。

采用上述技术方案,根据待存储数据中每个属性的属性特征,对待存储数据进行分类,将待存储数据分为属性特征为系统属性的第一类数据和属性特征为非系统属性的第二类数据,再分别存储至对应的存储分区。通过对待存储数据存储进行属性分区存储,将相同属性特征的数据集中存储在同一分区,且无需分行存储,一定程度避免产生大量的行数据。

附图说明

图1为本申请实施例中数据存储与检索的整体框架示意图;

图2为本申请实施例中数据存储方法的第一流程示意图;

图3为本申请实施例中uml类图的示意图;

图4为本申请实施例中数据分类方法的流程示意图;

图5为本申请实施例中属性值的预处理流程示意图;

图6为本申请实施例中数据分类后的存储方法的流程示意图;

图7为本申请实施例中数据检索方法的第一流程示意图;

图8为本申请实施例中数据检索方法的第二流程示意图;

图9为本申请实施例中数据检索方法的第二子流程示意图;

图10为本申请实施例中数据存储装置组成的结构示意图;

图11为本申请实施例中全文搜索引擎组成的第一结构示意图;

图12为本申请实施例中数据存储设备组成的结构示意图;

图13为本申请实施例中全文搜索引擎组成的第二结构示意图。

具体实施方式

为了能够更加详尽地了解本申请实施例的特点与技术内容,下面结合附图对本申请实施例的实现进行详细阐述,所附附图仅供参考说明之用,并非用来限定本申请实施例。

在介绍数据存储与检索方法之前,本申请提供一种数据存储与检索架构图,图1为本申请实施例中数据存储与检索的整体框架示意图。

如图1所示,数据存储与检索的整体框架主要包括api层、应用层、存储层。

api层包括restfulapi接口或rpcapi接口,通过restfulapi接口或rpcapi接口对外提供服务。

应用层中各个过滤器(filter)用于对属性实现不同功能的过滤,例如对属性中的文本或图片进行敏感信息过滤等,其中,不同filter实现不同过滤功能。应用层还封装了底层存储与检索复杂性,通过对具备不同属性特征的属性进行属性分区,即对待存储数据进行分类,将分类后的数据存储至存储层的对应的数据库中。

这里,待存储数据中可以包括正方形、三角形和圆形为3种不同的属性特征,针对不同属性特征设置不同分区范围,如正方形对应的分区范围为0~255,还可将0~255再划分为0~127和128~255;三角形对应的分区范围为256~511;圆形对应的分区范围为512~767。不同分区范围对应不同的读/写处理器,且不同分区范围对应不同的存储分区(即数据库)。其中,存储层的数据库包括oss数据库、mysql数据库及其他数据库(如redis数据库、hbase数据库)。

存储层还包括全文搜索引擎(elasticsearch,es),es用于从各个不同数据库中获取对应的数据,并进行聚合得到最终的检索结果。

下面分别对数据存储与数据检索进行具体阐述。

实施例一

本申请实施例提供了一种数据存储方法,图2为本申请实施例中数据存储方法的第一流程示意图,如图2所示,该数据存储方法具体可以包括:

步骤201:获取包括m个属性的待存储数据;其中,m为正整数;

需要说明的是,待存储数据相对于已存储数据,待存储数据指的是与已存储数据结构不相同的数据。

这里,使用课程类数据举例,若已存储数据包括点播课程,待存储数据包括付费课程,点播课程与付费课程有相同的属性(如课程名称等),也有各自独有的属性(如点播课程有视频相关属性,付费课程有价格相关属性)。可见,待存储数据的数据结构是随时发生变化的,故本申请的数据存储方法主要是针对异构数据存储方法。

步骤202:根据m个属性的属性特征对m个属性进行分类,得到属性特征为系统属性的第一类数据,以及属性特征为非系统属性的第二类数据;

需要说明的是,属性的属性特征包括系统属性和非系统属性。其中,系统属性为待存储数据中每个属性的共有属性,非系统属性为待存储数据中每个属性的非共有属性。

需要说明的是,步骤202主要是获取每个属性的属性特征,再根据每个属性的属性特征对m个属性进行分类。属性特征一般包括系统属性和非系统属性,故这里统计属性特征为系统属性的n个属性作为第一类数据,统计属性特征为非系统属性的p个属性作为第二类数据。其中,n+p=m,n和p为正整数。

在一些实施例中,所述待存储数据中每个属性包括第一属性标识和属性值;所述方法还包括:获取所述待存储数据对应的元数据;其中,所述元数据包括自定义属性信息,所述自定义属性信息包括:自定义属性特征及其对应的属性集合,所述属性集合中包括至少一个属性的第二属性标识;利用目标属性的第一属性标识以及第一属性标识和第二属性标识的映射关系,将所述元数据中对应的自定义属性特征作为所述目标属性的属性特征。

需要说明的是,该实施例为获取每个属性的属性特征的一种方法,该方法主要通过在待存储数据对应的元数据中预先自定义设置每个属性的属性特征,后续根据元数据中设定的属性特征确定待存储数据中对应属性的属性特征。

需要说明的是,待存储数据中每个属性包括第一属性标识和属性值,元数据为针对待存储数据中每个属性的第一属性标识的自定义属性信息,自定义属性信息至少包括自定义属性特征和第二属性标识。这里,确定目标属性的属性特征时,可利用待存储数据查询元数据,或者,利用元数据查询待存储数据。具体的,迭代待存储数据中每个属性的第一属性标识,根据映射关系确定第一属性标识对应的第二属性标识,将第二属性标识对应的自定义属性特征作为对应属性的属性特征;或者,迭代元数据中每条自定义属性信息,根据映射关系确定每条自定义属性信息中第二属性标识对应的第一属性标识,将第二属性标识对应的自定义属性特征作为对应属性的属性特征。

步骤203:将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区。

需要说明的是,步骤203主要是将上一步骤分类后的第一类数据和第二类数据分别存储至不同的存储分区,便于后续检索数据时可针对性检索,即若仅需要获取第一类数据,访问第一存储分区即可;若仅需要获取第二类数据,访问第二存储分区即可。

在一些实施例中,该步骤具体包括:利用所述映射关系,确定每个属性的第一属性标识对应的第二属性标识;将所述第一类数据中每个属性的第二属性标识作为key,属性值作为value,存储至所述第一存储分区;将所述第二类数据中每个属性的第二属性标识作为key,属性值作为value,存储至所述第二存储分区。

需要说明的是,存储属性特征为系统属性的第一类数据时,将每个属性的第一属性标识替换为第二属性标识并作为key,第一属性标识对应的属性值作为value,存储至第一存储分区。这里,第二属性标识可以是属性逻辑名称。

需要说明的是,存储属性特征为非系统属性的第二类数据时,将每个属性的第一属性标识替换为第二属性标识并作为key,第一属性标识对应的属性值作为value,存储至第二存储分区。这里,第二属性标识可以是属性id。属性的属性标识替换为属性id,即属性标识符引用,相对于繁琐的属性标识(如属性英文名称),便于后续修改,且节省一定空间。

在一些实施例中,所述自定义属性特征包括系统属性特征和多种非系统属性特征,所述第二存储分区包括多个第二子存储分区;所述将所述第二类数据存储至第二存储分区,包括:对所述第二类数据进行非系统属性分类,得到至少两种第三类数据;根据第三类数据的非系统属性类型,将所述第三类数据存储至对应的第二子存储分区。

需要说明的是,由于非系统属性特征包括多种,故需要对第二类数据再次进行分类。

这里,非系统属性特征至少包括基本属性或小文本属性、大文本属性和频繁更新属性。按照非系统属性特征类型将第二类数据分为三种第三类数据,即基本属性或小文本属性、大文本属性和频繁更新属性,再分别存储至对应的不同的第二子存储分区。

上述提及的频繁更新属性可以为浏览量。

在一些实施例中,所述自定义属性信息还包括自定义属性特征对应的分区标识;所述方法还包括:根据所述第一类数据的系统属性特征,在所述元数据中确定第一分区标识;根据所述第三类数据的非系统属性特征,在所述元数据中确定第二分区标识;所述将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区,包括:根据所述第一分区标识,将所述第一类数据存储到对应的第一存储分区;根据所述第二分区标识,将所述第三类数据存储到对应的第二子存储分区。

需要说明的是,在上一个实施例基础上,为了明确分辨每个属性的属性特征,该实施例针对系统属性特征和非系统属性特征,预先设置不同的分区标识;针对不同的非系统属性特征,也预先设置不同的分区标识。后续直接通过分区标识即可辨别至少两个属性的属性特征是否相同。

具体的,在元数据中确定第一类数据的分区标识为第一分区标识,基于第一分区标识确定预先设置的分区范围,再将第一类数据存储至分区范围对应的第一存储分区。在元数据中确定第二类数据的分区标识为第二分区标识,基于第二分区标识确定预先设置的分区范围,再将第二类数据存储至分区范围对应的第二子存储分区。这里,不同的分区范围对应不同的第二子存储分区。

示例性地,若系统属性特征的分区标识设置为0分区,非系统属性特征的分区标识设置为非0分区,具体针对非系统属性特征的基本属性或小文本属性设置的分区范围为1-127,针对非系统属性特征的大文本属性设置的分区范围为128-255,针对非系统属性特征的频繁更新属性设置的分区范围为256-511,针对非系统属性特征的唯一性约束属性设置的分区范围为512-767。这里,在元数据中确定第一类数据的分区标识为0分区,确定0分区对应的第一存储分区(如mysql数据库),再将第一类数据存储至mysql数据库。在元数据中确定第二类数据的分区标识为1分区,确定1分区对应的分区范围1-127,将第二类数据存储至分区范围1-127对应的第二子存储分区(如mysql数据库);在元数据中确定第二类数据的分区标识为128分区,确定128分区对应的分区范围为128-255,将第二类数据存储至分区范围128-255对应的第二子存储分区(如oss数据库);在元数据中确定第二类数据的分区标识为256分区,确定128分区对应的分区范围为256-511,将第二类数据存储至分区范围256-511对应的第二子存储分区(如mysql数据库);在元数据中确定第二类数据的分区标识为512分区,确定512分区对应的分区范围为512-767,将第二类数据存储至分区范围512-767对应的第二子存储分区(如mysql数据库)。

这里,步骤201至步骤203的执行主体可以为数据存储设备的处理器。

采用上述技术方案,根据待存储数据中每个属性的属性特征,对待存储数据进行分类,将待存储数据分为属性特征为系统属性的第一类数据和属性特征为非系统属性的第二类数据,再分别存储至对应的存储分区。通过对待存储数据存储进行属性分区存储,将相同属性特征的数据集中存储在同一分区,且无需分行存储,一定程度避免产生大量的行数据。

基于上述实施例,本申请提供示例一种uml类图,图3为本申请实施例中uml类图的示意图,如图3所示,具体的,

元数据指的是entity_type(实体类型)、entity_attribute(实体属性)和entity_attribute_enum(实体属性枚举)3张表。

这里,entity_type(实体类型)中属性包括:id(long)、root_id(long)、parent_id(long)、站点id(long)、命名空间(string)、实体名称(string)、实体复数别名(string)、实体单数别名(string)、json格式的配置信息(string)、版本号(int)、状态(int)、创建人(string)、修改人(string)、创建时间(date)、修改时间(date)。

其中,root_id(long)用于实现实体类型继承,子类型可以继承父类型的属性,也可以重写父类型的属性。

parent_id(long)用于实现实体类型继承,子类型可以继承父类型的属性,也可以重写父类型的属性。

站点id(long)用于支持不同站点,不同站点的数据逻辑隔离。如:商家帮助中心,商家学习中心等。

配置信息(string)是json数组格式,用于配置过滤器以及它们的执行顺序。每个对象通常有以下几个选项:filter(过滤器名称)、order(过滤器执行顺序)、params(过滤器的一些个性化参数,可选部分)。

版本号(int),实体版本号等于该实体属性集合中版本号最大的那个,用于实现不同版本数据的兼容。

entity_attribute(实体属性)中属性包括:id(long)、parent_id(long)、实体类型id(long)、属性名称(string)、属性别名(string)、系统属性(string)、数据类型(string)、正则校验(string)、数据分区(int)、文档的分隔符(es属性,string)、文档的分词器(es属性,string)、文档数据类型(es属性,string)、文档是否可搜(es属性,byte)、文档是否存储(es属性,byte)、文档嵌套对象(es属性,byte)、唯一约束分组(int)、唯一约束索引顺序(int)、是否必填(byte)、缺省值(string)、备注(string)、版本号(int)、状态(int)、创建人(string)、修改人(string)、创建时间(date)、修改时间(date)。

其中,parent_id(long)用于实现复合类型属性,属性可以是一个对象(普通对象或嵌套对象,依据查询方式的不同选择不同类型)。

实体类型id(long)指向实体类型表的主键,表明属性是属于哪个实体类型的。

属性名称(string),即属性的中文名称,用作注释。

属性别名(string),即属性的英文名称,系统会根据属性别名生成驼峰格式的名称(将下划线后紧跟的第一个字母变成大写并去掉下划线),并用于与客户端交互。命名规范:小写字母+数字+下划线的组合,数字不能出现在首位,各单词用下划线分开。

系统属性(string),特指entity表中的属性(或称通用属性、全局属性),由于各个业务系统的命名规则不一样,存储时需要在名称上做统一(属性别名映射到系统属性),检索时再进行逆操作(系统属性还原成属性别名)。如学习中心课程表的主键是course_id(属性别名),可以将它映射到系统属性的业务主键上,创建人可能是update_user,modifier等,可以将它们映射到系统属性修改人上。系统属性包括(parent_id,业务主键,状态,创建人,修改人,创建时间,修改时间)。

数据类型(string),即java数据类型。目前支持:byte,short,int,long,float,double,decimal,enum,date,string。

正则校验(string),即利用正则表达式验证属性的值是否合法,如:范围校验、长度检验等。

数据分区(int)是根据属性特征进行分区。例如:000~255:json分区。000:分区0是系统分区,不存储任何数据,系统属性的分区固定为0。001~127:基础数据分区,基本类型属性或小文本属性。128~255:oss分区,超长文本、大对象、文件、图片。256~511:统计类、数值类(频繁更新)分区。512~767:uniquekey分区,保证属性值的唯一性,与唯一约束分组与索引配合使用。

文档的分隔符(es属性,string),用于将原始字符串数据(如:招商入驻,平台规则,行业标准)按指定分隔符转换成数组存储,以方便根据单个或多个值进行检索。

文档的分词器(es属性,string),即构建全文索引时用的分词器。

文档数据类型(es属性,string),目前支持:byte,short,integer,integer_range,long,long_range,float,float_range,double,double_range,boolean,date,date_range,ip,ip_range,keyword,text。

唯一约束索引顺序(int),即只有当数据分区在uniquekey分区范围内的时候,该字段才有效。相同uniquekey分区的属性通过索引顺序(sequence)生成hash值,类似数据库的seq_in_index,从1开始。例如:对活动实体中的两个属性(app_key,外部活动id)创建唯一约束,这两个属性的数据分区都是512,app_key的索引顺序是1,外部活动id的索引顺序是2。计算hash的方式hash(app_key:外部活动id)。

是否必填(byte),指的是属性的值是否必填的。

缺省值(string),当值为空时,显示的缺省值。

版本号(int),属性版本号,实现属性的多个版本共存。例如:v1版本中,文章摘要属性和所有其他所有属性都存储在分区1中。因业务发展需要,摘要的长度变大,需要存储到oss分区中。增加摘要属性的v2版本,分区为128。这时系统中新旧数据是共存的,如果数据的版本号是v1(entity表中version),则从分区1中查找摘要信息,如果版本号是v2,则从分区128的oss存储中查找摘要信息。

entity_attribute_enum(实体属性枚举)中属性包括:id(long)、属性id(long)、枚举索引(int)、枚举键(string)、枚举值(string)、状态(int)、创建人(string)、修改人(string)、创建时间(date)、修改时间(date)。

其中,属性id(long)指向实体属性表的主键。

枚举索引(int),即枚举编码,是一个数字,存储层通常用这个值。

枚举键(string),英文名称,通常对应java枚举类的ordinalname。

枚举值(string),中文名称,对应自定义的枚举名称,用于描述枚举。

根据上述元数据中属性的属性特征对待存储数据进行分类处理后,得到四张表,包括:entity(实体)、entity_unique(实体唯一性约束)、entity_text(实体值-json)和entity_long(实体值-数值)。

这里,entity(实体)中属性包括:id(long)、parent_id(long)、业务主键(long)、实体类型id(long)、语言(int)、版本号(int)、状态(int)、创建人(string)、修改人(string)、创建时间(date)、修改时间(date)。

其中,parent_id(long)实现to-one关联:一条评论有多个回复,那么每个回复的parent_id指向评论;实现多语言,主语言数据下有多条子语言数据,每条子语言的parent_id指向主语言。

实体类型id(long)用于指向实体类型表的主键。

语言(int)用于支持国际化,或一个站点多语言。

状态(int)指的是业务数据的状态,负数为无效数据。

entity_unique(实体唯一性约束)中属性包括:id(long)、实体类型id(long)、实体id(long)、数据分区(int)、哈希(long)、值_255byte(string)。

其中,实体id(long)用于指向实体表的主键。

实体类型id(long)用于指向实体类型表的主键。

数据分区(int)是根据属性特征进行分区。例如:000~255:json分区。000:分区0是系统分区,不存储任何数据,系统属性的分区固定为0。001~127:基础数据分区,基本类型属性或小文本属性,相同分区的属性会以json格式存储在一起。128~255:oss分区(即oss数据库存储),存储超长文本、大对象、文件、图片等,存储时只存储一个链接或可以唯一表示这个对象的key。256~511:统计类、数值类(频繁更新)分区。512~767:uniquekey分区,保证属性值的唯一性,与唯一约束分组与索引配合使用。

哈希(long),对具有相同分区的属性值,按顺序拼接,并进行哈希计算(hash(ie93jd34:20001)),该字段只是为了缩小查询范围(当发生哈希碰撞时),所以还需要比较值是否相等。对这三个[实体类型id,数据分区,哈希]数值类字段添加普通索引即可,在应用层通过写锁(select…forupdate)或读(lockinsharemode)锁来判断是否有重复数据,过滤条件如下:

where实体类型id=?and数据分区=?and哈希=?and值=?

值_255byte(string),json格式,例如:{"21":"ie93jd34","28":"20001"}。

entity_text(实体值-json)中属性包括:id(long)、实体id(long)、数据分区(int)、值(json,8192byte,string)。

其中,实体id(long)用于指向实体表的主键。

数据分区(int)是根据属性特征进行分区。例如:000~255:json分区。000:分区0是系统分区,不存储任何数据,系统属性的分区固定为0。001~127:基础数据分区,基本类型属性或小文本属性,相同分区的属性会以json格式存储在一起。128~255:oss分区(即oss数据库存储),存储超长文本、大对象、文件、图片等,存储时只存储一个链接或可以唯一表示这个对象的key。256~511:统计类、数值类(频繁更新)分区。512~767:uniquekey分区,保证属性值的唯一性,与唯一约束分组与索引配合使用。

entity_long(实体值-数值)中属性包括:id(long)、实体id(long)、属性id_0(long)、属性id_1(long)、值_0(long)、值_1(long)。

其中,实体id(long)用于指向实体表的主键。

属性id_0(long)用于指向实体属性表的主键。规则:数据分区范围在256~511的属性会[must]存储在这里,通常用于频繁更新的数值类字段。一个实体类型下,不同属性的分区在256~511这个范围内不能[mustnot]重复。

值_0(long),即属性的值。

属性id_1(long),可选部分,当大部分实体类型都拥有至少2~4个频繁更新的数值类属性时,可以适当扩展此表,增加多个键值对,键对应属性id,值对应属性的值。

值_1(long),即属性的值。

这里,还包括entity_relationship(实体关联关系),其属性包括:id(int)、实体id-source_id(int)、实体id-target_id(int)和状态(int)。

其中,实体id-source_id(int)、实体id-target_id(int)用于实现to-many关联,例如:给定用户,找用户关注的店铺列表,如果用户实体类型(entity_type)id小于店铺实体类型id,条件为:source_id={user_id},查询出来的target_id列表即为店铺实体的ids列表,否则条件为:target_id={user_id},查询出来的source_id列表即为店铺实体的ids列表。给定店铺,找店铺被哪些用户关注,反之亦然。

状态(int),状态1表示有效,状态-1表示删除。

针对图3中出现的1..1表示另一个类的一个对象只与该类的一个对象有关系,0..*表示另一个类的一个对象与该类的零个或多个对象有关系,1..*表示另一个类的一个对象与该类的一个或多个对象有关系,0..1表示另一个类的一个对象没有或只与该类的一个对象有关系。

实施例二

在上述实施例基础上,本申请还给出一种数据存储方法,该数据存储方法包括数据分类方法(即图4和图5)和数据分类后的存储方法(即图6)。

图4为本申请实施例中数据分类方法的流程示意图,如图4所示,具体步骤可以包括:

步骤401:开始;

步骤402:待存储数据及对应的元数据;

这里,待存储数据包括m个属性,元数据为针对每个属性的自定义属性信息。

步骤403:从元数据中获取自定义属性信息集合;

这里,自定义属性信息集合包括每个属性对应的自定义属性信息,自定义属性信息包括自定义属性特征和其他属性集合,其他属性集合中包括属性逻辑名。

步骤404:迭代自定义属性信息集合;

即依次迭代自定义属性信息集合中每个属性对应的自定义属性信息。

步骤405:是否有下一个;若是,执行步骤406;若否,执行步骤413;

步骤406:获取下一个属性的自定义属性信息;

步骤407:根据自定义属性信息中属性逻辑名查找待存储数据中对应属性的第一属性标识;

上述提及的m个属性中每个属性包括第一属性标识和属性值,元数据的自定义属性信息中包括每个属性的逻辑名(即第二属性标识),每个属性的逻辑名与第一属性标识存在映射关系,可根据属性的逻辑名查找待存储数据中对应的属性的第一属性标识,使得属性的逻辑名对应的自定义属性特征即为待存储数据中对应的属性的属性特征。

这里,通常执行步骤407后,会对属性值进行一些预处理,即步骤501至步骤509。

图5为本申请实施例中属性值的预处理流程示意图。如图5所示,具体步骤包括如下:

步骤501:是否设置缺省值;若是,执行步骤502;若否,执行步骤503;

缺省值指的是默认值。这里,设置缺省值、不为空,且实体属性的属性值为空时,执行步骤502;实体属性的属性值不为空时,执行步骤503。

步骤502:将缺省值转换成该属性元数据中指定的数据类型;

步骤503:将实体属性的属性值转换成该属性元数据中指定的数据类型;

步骤502和步骤503通过datatype.apply实现数据类型转换,datatype是自定义的数据类型枚举,实现了java的function函数接口,apply方法用于进行数据类型的转换,不同枚举类型有各自的实现。

步骤504:数据类型校验;

步骤505:是否必填检验值正则表达式校验;

步骤506:是否必填校验值范围校验;

步骤505和步骤506通过datatype.test实现数据类型校验,datatype是自定义的数据类型枚举,实现了java的bipredicate函数接口,test方法用于进行数据类型的校验。

步骤507:是否通过校验;若是,执行步骤508;若否,执行步骤509;

步骤508:属性值是否为空;若是,执行步骤412;若否,执行步骤408;

步骤509:抛出异常错误信息;

步骤408:属性是否为系统属性;若是,执行步骤409;若否,执行步骤410;

这里,系统属性为待存储数据中每个属性的共有属性,非系统属性为待存储数据中每个属性的非共有属性。

这里,若属性为系统属性,即对应0分区;若属性为非系统属性,即对应非0分区。

步骤409:获取该属性在元数据中映射的属性逻辑名并作为key;

步骤410:获取该属性在元数据中的属性id并作为key;

步骤411:将属性值设置在与之对应的属性分区集合中;

步骤412:完成当前属性处理;

步骤413:处理系统属性集合将值填充到实体的系统属性上;

步骤414:迭代非系统属性分区集合,key=分区号,value=属性集合;

步骤415:构建实体值对象实例,设置分区,设置json值;

步骤416:为当前实体设置实体值对象集合;

步骤417:结束。

基于图4和图5中步骤,若待存储数据包括key1-value1、key2-value2、key3-value3…keyn-valuen,进行分类后的待存储数据为:分区0包括key1-value1和key2-value2;分区1包括key3-value3、key4-value4和key5-value5;分区128包括key6-value6;分区256包括key7-value7。这里,相同分区可存储至少一个不同属性。另外,还可根据需求继续分区,这里不再具体阐述。

针对非系统属性特征需要将不同分区的数据存储至不同的存储分区,故本申请给出一种针对非系统属性特征数据分类后的存储方法。图6为本申请实施例中数据分类后的存储方法的流程示意图。

如图6所示,具体步骤可以包括:

步骤601:根据属性的分区标识获取所在分区范围;若分区范围为1~127,执行步骤602;若分区范围为128~255,执行步骤603;若分区范围为256~511,执行步骤607;若分区范围为512~767,执行步骤609;

步骤602:确定1~127分区范围的处理器;

这里,1~127分区范围存储基本属性或小文本数据的相关数据。

1~127分区范围的处理器通过entitytext对象操作对应的存储分区(如mysql数据库),具体是执行步骤613,若判断出存在主键,说明需要更新原先存储的数据,即执行步骤615;若判断出不存在主键,说明需要更新原先存储的数据,即执行步骤614。

步骤603:确定128~255分区范围的处理器;

步骤604:生成oss唯一key;

步骤605:将大文本写入oss,并获取写入结果md5;

步骤606:将key和md5作为新的值,替换原始内容为指向oss文件的链接;

这里,128-255分区范围存储大文本属性的相关数据,具体存储时存储对应的一个链接。

利用128-255分区范围的处理器通过entitytext对象操作对应的存储分区(如oss数据库),具体是执行步骤613,若判断出存在主键,说明需要更新原先存储的数据,即执行步骤615;若判断出不存在主键,说明需要更新原先存储的数据,即执行步骤614。

步骤607:确定256~511分区范围的处理器;

步骤608:将entitytext对象转换为entitylong对象;

这里,256~511分区范围存储频繁更新属性的相关数据。

利用256~511分区范围的处理器通过将entitytext对象转换为entitylong对象,再操作对应的存储分区(如mysql数据库),具体是执行步骤613,若判断出存在主键,说明需要更新原先存储的数据,即执行步骤615;若判断出不存在主键,说明需要更新原先存储的数据,即执行步骤614。

步骤609:确定512~767分区范围的处理器;

这里,512~767分区范围存储唯一性约束相关数据。512~767分区范围的处理器通常高于其他分区范围的处理器。

步骤610:将entitytext对象转换为entityunique对象;

利用512~767分区范围的处理器将entitytext对象转换为entityunique对象。

步骤611:写锁方式/读锁方式;

该步骤为保证联合属性的全局唯一性,512~767分区范围不支持更新操作。

步骤612:根据元数据中的联合唯一key的顺序生成hash值;

步骤613:是否存在主键;若是,执行步骤614;若否,执行步骤615;

步骤614:insert数据库;

步骤615:update数据库。

基于上述步骤,还可继续进行分区,针对不同分区范围设置不同存储分区,如hbase数据库。这里不再具体阐述。

采用上述技术方案,根据待存储数据中每个属性的属性特征,对待存储数据进行分类,将待存储数据分为属性特征为系统属性的第一类数据和属性特征为非系统属性的第二类数据,再分别存储至对应的存储分区。通过对待存储数据存储进行属性分区存储,将相同属性特征的数据集中存储在同一分区,且无需分行存储,一定程度避免产生大量的行数据。

实施例三

本申请实施例提供了一种数据检索方法,图7为本申请实施例中数据检索方法的第一流程示意图,如图7所示,该数据检索方法应用于全文搜索引擎,具体步骤可以包括:

步骤701:获取检索信息;

需要说明的是,借助全文搜索引擎(elasticsearch,es)获取检索信息。

这里,es可以实现异构属性的动态添加,它定义了这些动态添加的属性应按何种方式映射到合适的数据类型上,达到与存储数据的数据库无缝链接与索引外置目的。

具体的,es通过动态模板(dynamictemplates)技术构建索引,自动与各个数据库建立属性映射关系,即当数据库中某个属性新增加一个新的自定义属性信息并插入数据后,es会自动根据这条数据所属的属性类型的元数据信息创建缺失的属性信息,具备灵活性,可以很好的实现对异构数据的检索,故本申请通过es实现对数据的检索操作。

这里,为了避免构建索引时单个索引(index)中属性信息太多(超过1000个),可以创建n个相同结构的index,并使用一致性哈希计算,这样固定站点的所有数据就会落在同一个index中,保证每个index的属性信息个数不会超过预设阈值。

步骤702:根据所述检索信息确定n个第一属性标识;其中,n为正整数;

需要说明的是,es获取到检索信息,并确定出检索信息中包括的n个第一属性标识,es具体是根据n个第一属性标识执行检索操作。

步骤703:根据所述n个第一属性标识查找存储分区,获取对应的n段检索数据;其中,所述存储分区是按照属性特征对属性进行分区存储;

需要说明的是,由于数据存储时是根据属性的属性特征将其存储至不同的存储分区,故获取时可针对需要获取的检索数据确定存储分区,直接从确定的存储分区获取即可,不需要获取不必的数据,提升一定检索速度。

这里,借助es实现数据检索时,屏蔽了不同底层存储技术的复杂性,提供统一检索入口,可快速从不同存储分区中获取对应数据。

在一些实施例中,具体步骤包括:基于预先设定的每个第一属性标识与对应的第二属性标识的映射关系,确定所述n个第一属性标识的n个第二属性标识;基于所述n个第二属性标识查找存储分区,获取所述n段检索数据。

这里,利用es实现数据检索时,是不能直接根据属性的第二属性标识获取存储的数据(即属性值),需要对属性的第二属性标识进行替换,利用替换后的标识(后面均称为第三属性标识)去查找对应的检索数据,故这里预先对每个属性的第二属性标识自定义设置对应的第三属性标识。

具体的,输入属性的第一属性标识,检索时需要将第一属性标识对应的第二属性标识替换为第三属性标识,通过第三属性标识获取对应的检索数据,后续再将第三属性标识替换为第二属性标识,即可获取第二属性标识对应的检索数据,也就获取了第一属性标识对应的检索数据。

示例性地,若查询讲师名称等于王某某的课程,输入的第一属性标识为王某某,存储时的第二属性标识可以为:${teacher_name}=王某某,而实际利用es检索时,使用的是属性的物理名称:keyword_12=王某某(即第三属性标识)。这里,实际应用中是通过占位符替换流程完成将${teacher_name}=王某某替换为keyword_12=王某某。

步骤704:按照预设聚合策略对所述n段检索数据进行聚合,得到所述检索信息对应的检索结果。

需要说明的是,预设聚合策略为按照n个第一属性标识的排列顺序进行聚合的策略。即按照n个第一属性标识的排列顺序对得到的n段检索数据进行聚合,得到n个第一属性标识对应的检索结果。

采用上述技术方案,利用全文搜索引擎从不同存储分区中分别对n个第一属性标识进行检索,得到n段检索数据,对n段检索数据聚合得到检索结果。由于全文搜索引擎提供统一检索接口,屏蔽了从不同存储分区中检索及聚合数据的复杂性,提升检索效率。

实施例四

本申请实施例还提供了一种数据检索方法,图8为本申请实施例中数据检索方法的第二流程示意图。

如图8所示,具体步骤包括如下:

步骤801:检索dsl解析(原始检索);

这里,特定领域语言(domainspecificlanguage,dsl)用于对需要检索的属性的第一属性标识进行解析。

若第一属性标识为王某某,解析后对应的第二属性标识可以为:${teacher_name}=王某某。

步骤802:第一次占位符替换;

通过占位符替换流程完成将${teacher_name}=王某某替换为keyword_12=王某某(第三属性标识)。

步骤803:检索dsl安全性包装;

步骤804:构建es检索条件;

检索条件包括步骤805中至少一个条件。

步骤805:多语言;分页相关信息和聚合相关信息;查询第一属性标识includes/excludes;构建排序缺省按创建时间降序;路由信息;

步骤806:利用es执行检索,得到对应的检索结果;

这里,得到keyword_12=王某某(第三属性标识)对应的检索结果。

步骤807:第二次占位符替换;

通过占位符替换流程完成将keyword_12=王某某(第三属性标识)替换为${teacher_name}=王某某。

步骤808:处理检索结果。

这里,待存储数据中每个属性对应的元数据包括多个自定义属性信息,不同自定义属性信息对应不同分区,检索时可能只检索指定分区的数据,也可能检索该属性的所有分区的数据,故本申请对步骤801中解析内容进一步限定,即限定所要检索的分区,图9为本申请实施例中数据检索方法的第二子流程示意图。

如图9所示,具体步骤包括如下:

步骤901:是否只查询指定分区的数据;若是,执行步骤902;若否,执行步骤903;

步骤902:构建指定分区范围的集合;

步骤903:构建元数据中包含的所有分区范围的集合;

步骤904:迭代分区范围集合;

步骤905:是否有下一个;若否,执行步骤906;若是,执行步骤907;

步骤906:表征检索完成;

步骤907:根据分区范围查找对应的读处理器;

步骤908:请求任务拆分;

步骤909:确定1~127分区范围的读处理器,检索对应的数据库,得到第一数据;

步骤910:确定128~255分区范围的读处理器,检索对应的数据库,得到第二数据;

步骤911:确定265~511分区范围的读处理器,检索对应的数据库,得到第三数据;

步骤912:确定512~767分区范围的读处理器,检索对应的数据库,得到第四数据;

步骤913:对第一数据、第二数据、第三数据和第四数据进行聚合操作,得到对应的聚合结果。

基于上述步骤,本申请这种根据属性的属性特征进行分区存储后,在检索时,可针对性检索所需分区范围对应的数据,就不需要检索其他分区范围对应的数据,提升一定检索效率。

采用上述技术方案,利用全文搜索引擎从不同存储分区中分别对n个第一属性标识进行检索,得到n段检索数据,对n段检索数据聚合得到检索结果。由于全文搜索引擎提供统一检索接口,屏蔽了从不同存储分区中检索及聚合数据的复杂性,提升检索效率。

实施例五

为实现本申请实施例的方法,基于同一发明构思,本申请实施例中还提供了一种数据存储装置,图10为本申请实施例中数据存储装置组成的结构示意图。如图10所示,该数据存储装置包括:

第一获取单元1001,用于获取包括m个属性的待存储数据;其中,m为正整数;

分类单元1002,用于根据m个属性的属性特征对m个属性对进行分类,得到属性特征为系统属性的第一类数据,以及属性特征为非系统属性的第二类数据;

存储单元1003,用于将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区。

在一些实施例中,所述待存储数据中每个属性包括第一属性标识和属性值;所述方法还包括:获取所述待存储数据对应的元数据;其中,所述元数据包括自定义属性信息,所述自定义属性信息包括:自定义属性特征及其对应的属性集合,所述属性集合中包括至少一个属性的第二属性标识;利用目标属性的第一属性标识以及第一属性标识和第二属性标识的映射关系,将所述元数据中对应的自定义属性特征作为所述目标属性的属性特征。

在一些实施例中,该装置包括存储单元1003,具体用于利用所述映射关系,确定每个属性的第一属性标识对应的第二属性标识;将所述第一类数据中每个属性的第二属性标识作为key,属性值作为value,存储至所述第一存储分区;将所述第二类数据中每个属性的第二属性标识作为key,属性值作为value,存储至所述第二存储分区。

在一些实施例中,所述自定义属性特征包括系统属性特征和多种非系统属性特征,所述第二存储分区包括多个第二子存储分区;所述将所述第二类数据存储至第二存储分区,包括:对所述第二类数据进行非系统属性分类,得到至少两种第三类数据;根据第三类数据的非系统属性类型,将所述第三类数据存储至对应的第二子存储分区。

在一些实施例中,所述自定义属性信息还包括自定义属性特征对应的分区标识;所述方法还包括:根据所述第一类数据的系统属性特征,在所述元数据中确定第一分区标识;根据所述第三类数据的非系统属性特征,在所述元数据中确定第二分区标识;所述将所述第一类数据存储至第一存储分区,将所述第二类数据存储至第二存储分区,包括:根据所述第一分区标识,将所述第一类数据存储到对应的第一存储分区;根据所述第二分区标识,将所述第三类数据存储到对应的第二子存储分区。

采用上述技术方案,根据待存储数据中每个属性的属性特征,对待存储数据进行分类,将待存储数据分为属性特征为系统属性的第一类数据和属性特征为非系统属性的第二类数据,再分别存储至对应的存储分区。通过对待存储数据存储进行属性分区存储,将相同属性特征的数据集中存储在同一分区,且无需分行存储,一定程度避免产生大量的行数据。

实施例六

为实现本申请实施例的方法,基于同一发明构思,本申请实施例中还提供了一种全文搜索引擎,图11为本申请实施例中全文搜索引擎组成的第一结构示意图。如图11所示,该全文搜索引擎包括:

第二获取单元1101,获取检索信息;

确定单元1102,用于根据所述检索信息确定n个第一属性标识;其中,n为正整数;

查找单元1103,根据所述n个第一属性标识查找存储分区,获取对应的n段检索数据;其中,所述存储分区是按照属性特征对属性进行分区存储;

聚合单元1104,按照预设聚合策略对所述n段检索数据进行聚合,得到所述检索信息对应的检索结果。

在一些实施例中,该装置包括:查找单元1103,具体用于基于预先设定的每个第一属性标识与对应的第二属性标识的映射关系,确定所述n个第一属性标识的n个第二属性标识;基于所述n个第二属性标识查找存储分区,获取所述n段检索数据。

在一些实施例中,该装置包括:聚合单元1104,具体用于按照所述n个第一属性标识的排列顺序,对所述n段检索数据进行聚合,得到所述检索结果。

采用上述技术方案,利用全文搜索引擎从不同存储分区中分别对n个第一属性标识进行检索,得到n段检索数据,对n段检索数据聚合得到检索结果。由于全文搜索引擎提供统一检索接口,屏蔽了从不同存储分区中检索及聚合数据的复杂性,提升检索效率。

本申请实施例还提供了另一种数据存储设备,图12为本申请实施例中数据存储设备组成的结构示意图。如图12所示,该数据存储设备包括:处理器1201和配置为存储能够在处理器上运行的计算机程序的存储器1202;

其中,处理器1201配置为运行计算机程序时,执行前述实施例中的方法步骤。

当然,实际应用时,如图12所示,该数据存储设备中的各个组件通过总线系统1203耦合在一起。可理解,总线系统1203用于实现这些组件之间的连接通信。总线系统1203除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图12中将各种总线都标为总线系统1203。

本申请实施例还提供了另一种全文搜索引擎,图13为本申请实施例中全文搜索引擎组成的第二结构示意图。如图13所示,该全文搜索引擎包括:处理器1301和配置为存储能够在处理器上运行的计算机程序的存储器1302;

其中,处理器1301配置为运行计算机程序时,执行前述实施例中的方法步骤。

当然,实际应用时,如图13所示,该全文搜索引擎中的各个组件通过总线系统1303耦合在一起。可理解,总线系统1303用于实现这些组件之间的连接通信。总线系统1303除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图13中将各种总线都标为总线系统1303。

在实际应用中,上述处理器可以为特定用途集成电路(asic,applicationspecificintegratedcircuit)、数字信号处理装置(dspd,digitalsignalprocessingdevice)、可编程逻辑装置(pld,programmablelogicdevice)、现场可编程门阵列(field-programmablegatearray,fpga)、控制器、微控制器、微处理器中的至少一种。可以理解地,对于不同的设备,用于实现上述处理器功能的电子器件还可以为其它,本申请实施例不作具体限定。

上述存储器可以是易失性存储器(volatilememory),例如随机存取存储器(ram,random-accessmemory);或者非易失性存储器(non-volatilememory),例如只读存储器(rom,read-onlymemory),快闪存储器(flashmemory),硬盘(hdd,harddiskdrive)或固态硬盘(ssd,solid-statedrive);或者上述种类的存储器的组合,并向处理器提供指令和数据。

在示例性实施例中,本申请实施例还提供了一种计算机可读存储介质,用于存储计算机程序。

可选的,该计算机可读存储介质可应用于本申请实施例中的任意一种方法,并且该计算机程序使得计算机执行本申请实施例的各个方法中由处理器实现的相应流程,为了简洁,在此不再赘述。

在本申请所提供的几个实施例中,应该理解到,所揭露的设备和方法,可以通过其它的方式实现。以上所描述的设备实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,如:多个单元或组件可以结合,或可以集成到另一个系统,或一些特征可以忽略,或不执行。另外,所显示或讨论的各组成部分相互之间的耦合、或直接耦合、或通信连接可以是通过一些接口,设备或单元的间接耦合或通信连接,可以是电性的、机械的或其它形式的。

上述作为分离部件说明的单元可以是、或也可以不是物理上分开的,作为单元显示的部件可以是、或也可以不是物理单元,即可以位于一个地方,也可以分布到多个网络单元上;可以根据实际的需要选择其中的部分或全部单元来实现本实施例方案的目的。

另外,在本发明各实施例中的各功能单元可以全部集成在一个处理模块中,也可以是各单元分别单独作为一个单元,也可以两个或两个以上单元集成在一个单元中;上述集成的单元既可以采用硬件的形式实现,也可以采用硬件加软件功能单元的形式实现。本领域普通技术人员可以理解:实现上述方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成,前述的程序可以存储于一计算机可读取存储介质中,该程序在执行时,执行包括上述方法实施例的步骤;而前述的存储介质包括:移动存储设备、只读存储器(rom,read-onlymemory)、随机存取存储器(ram,randomaccessmemory)、磁碟或者光盘等各种可以存储程序代码的介质。

本申请所提供的几个方法实施例中所揭露的方法,在不冲突的情况下可以任意组合,得到新的方法实施例。

本申请所提供的几个产品实施例中所揭露的特征,在不冲突的情况下可以任意组合,得到新的产品实施例。

本申请所提供的几个方法或设备实施例中所揭露的特征,在不冲突的情况下可以任意组合,得到新的方法实施例或设备实施例。

以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应以所述权利要求的保护范围为准。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1