CN105718515B - 数据存储系统及其方法和数据分析系统及其方法 - Google Patents
数据存储系统及其方法和数据分析系统及其方法 Download PDFInfo
- Publication number
- CN105718515B CN105718515B CN201610024279.6A CN201610024279A CN105718515B CN 105718515 B CN105718515 B CN 105718515B CN 201610024279 A CN201610024279 A CN 201610024279A CN 105718515 B CN105718515 B CN 105718515B
- Authority
- CN
- China
- Prior art keywords
- data
- storage
- column
- attribute
- subclass
- 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
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/242—Query formulation
- G06F16/2428—Query predicate definition using graphical user interfaces, including menus and forms
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2291—User-Defined Types; Storage management thereof
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/242—Query formulation
- G06F16/2433—Query languages
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/25—Integrating or interfacing systems involving database management systems
- G06F16/258—Data format conversion from or to a database
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Databases & Information Systems (AREA)
- Physics & Mathematics (AREA)
- Data Mining & Analysis (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Mathematical Physics (AREA)
- Computational Linguistics (AREA)
- Software Systems (AREA)
- Human Computer Interaction (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明提供一种数据存储系统,其包括:数据获取装置,其适于获取需要存储的数据;数据解析装置,其适于将所述数据获取装置获取的所述需要存储的数据进行解析,获得需要存储的数据的特征并确定存储位置;元数据记录装置,其适于记录所述需要存储的数据的元数据信息,所述元数据信息包括所述需要存储的数据的特征及存储位置;以及数据存储装置,其适于基于所述元数据记录装置记录的元数据信息,将所述数据解析装置解析出的数据存储在相应的存储位置。另外,本发明还提供一种数据存储方法及数据分析系统及方法。利用本发明,可以灵活、有序地实现数据存储,尤其在有大量数据需要存储的情形下。
Description
技术领域
本发明涉及计算机和通信技术领域,尤其涉及数据存储方法及装置和数据分析方法及装置。
背景技术
当大量、多种类数据实时传输并存储时,需要能够快速、有序地存储、从而方便快速、有序地查询。现有技术中,存储的数据种类通常是预先设定好的,不能随意增加的新的数据种类,即使新增加了,在存储时也会被认为是异常而被丢弃。
例如,在大数据统计分析中,每时每刻都可能会有大量数据产生,统计的数据种类可能会随着用户的需求的不同而变化,因此,要求能够更灵活地对数据种类进行增加或者改变。但现有的数据统计分析工具在需要增加新的数据种类时,往往需要对统计分析工具进行升级或重新安装,不仅服务器侧需要升级或重新安装,客户端侧也要进行相应的升级或重新安装,这对于使用统计分析工具的用户(例如电子商务平台或者APP开发者)来说,比较麻烦。如果重新安装,还可能存在不能将以往的数据导入新的统计分析工具中或者造成某些数据的丢失的,因此,目前的统计分析工具缺少灵活性,不适应快速发展、变化的电商经营者及APP开发者的需求,导致其统计分析结果只具有一定程度的参考价值,不能很大程度上地依赖。因此,需要有一种灵活的数据存储机制。
发明内容
为解决现有存在的技术问题,本发明提供一种数据存储系统及方法,其能将连续不断的数据有序、快速地进行存储,并使得对存储的数据的查询更高效。
为达到上述目的,本发明实施例的技术方案是这样实现的:
根据本发明的一个方面,提供一种数据存储系统,适用于对不断采集的大量数据进行存储,且所述不断采集的数据存在着变化,其特征在于,所述采集的数据根据用户需求而设置有多个数据种类,且所述数据种类是根据用户需求的变化而可变化的,所述数据种类基于数据的特征而划分成多个数据种类,所述数据的特征包括数据类别、子类别、属性,其中所述类别包括一个或多个子类别,每个子类别分别具有一种或多种属性。所述数据存储系统包括:数据获取装置,其适于获取需要存储的数据,所述需要存储的数据为从客户端或服务器侧不断采集的数据在经过转换和处理后而需要进行存储的数据;数据解析装置,其适于将所述数据获取装置获取的所述需要存储的数据进行解析,获得所述需要存储的数据的特征并根据所述需要存储的数据的特征确定所述需要存储的数据的存储位置;元数据记录装置,其适于记录所述需要存储的数据的元数据信息,所述元数据信息包括所述需要存储的数据的特征及存储位置;以及数据存储装置,其适于基于所述元数据记录装置记录的元数据信息,将所述数据解析装置解析出的数据存储在相应的存储位置。
根据本发明的另一方面,提供一种数据存储方法,适用于对不断采集的大量数据进行存储,且所述不断采集的数据存在着变化,所述采集的数据根据用户需求而设置有多个数据种类,且所述数据种类是根据用户需求的变化而可变化的,所述数据种类基于数据的特征而划分成多个数据种类,所述数据的特征包括数据类别、子类别、子类别的属性,其中所述类别包括一个或多个子类别,每个子类别分别具有一种或多种属性。所述数据存储方法包括:获取需要存储的数据,所述需要存储的数据为从客户端或服务器侧不断采集的数据在经过转换和处理后而需要进行存储的数据;对所述需要存储的数据进行解析,获得所述需要存储的数据的特征并根据所述需要存储的数据的特征确定所述需要存储的数据的存储位置;记录所述需要存储的数据的元数据信息,所述元数据信息包括所述需要存储的数据的特征及存储位置;以及基于所记录的元数据信息,将所述解析出的数据存储在相应的存储位置。
根据本发明的又一方面,提供一种数据查询装置,其适于对根据前面所述的数据存储系统存储的数据进行查询,其包括:第一接收模块,其适于接收来自WEB前端的查询请求,所述查询请求包含一个或多个查询条件和一个或多个显示参数;第二解析模块,其适于基于所述数据存储系统的元数据记录装置中记录的元数据信息解析所述查询请求,获得解析结果;查询机制建立模块,其适于基于所述第二解析模块的解析结果建立查询机制;第一查询模块,其适于根据所建立的查询机制查询所述数据存储系统中的数据存储装置中的数据,获得查询结果;第一存储模块,其适于存储所述查询结果,以及第一发送模块,其适于将所述查询结果发送给所述WEB前端。
根据本发明又一方面,提供一种数据查询方法,其对根据前面所述的数据存储方法存储的数据进行查询,其包括:获取来自WEB前端的查询请求,所述查询请求包含一个或多个查询条件和一个或多个显示参数;基于被存储的数据的元数据信息,解析所述查询请求中包含的查询条件和显示参数,获得解析结果;基于所述解析结果构建查询机制;基于所构建的查询机制查询所述存储的数据,获取查询结果;以及将所述查询结果发送至所述WEB前端。
根据本发明的又一方面,提供一种数据展现系统,其包括:显示装置,其位于WEB前端,适于接收使用者对查询条件和显示参数的输入、以及显示基于所述查询条件和显示参数所获得的查询结果;第二接收模块,其位于WEB服务器中,适于接收所述查询条件和显示参数,并传送至根据前面所述的数据查询装置;根据前面所述的数据查询装置,适于根据所述查询条件和显示参数,查询前面所述的数据存储系统中的数据存储装置存储的数据,获得查询结果;以及获取模块,其位于WEB服务器中,适于从所述数据查询装置中获取所述查询结果,并将所述查询结果发送至所述显示装置。
根据本发明的又一方面,提供一种数据展现方法,包括:接收使用者输入的查询条件和显示参数;根据所述查询条件和显示参数,采用前面所述的数据查询方法,查询根据前面所述的数据存储方法存储的数据,获得查询结果;以及将所述查询结果发送至WEB前端进行展现。
根据本发明的又一方面,提供一种数据分析系统,其包括:数据采集系统,其适于从客户端和/或服务器中采集数据,所述采集的数据包含根据用户需求而设置的多个数据种类;数据传输系统,其适于将所述数据采集系统所采集的数据进行提取、转换并传输;根据前面所述的数据存储系统,其适于将所述数据传输系统传输的数据进行存储、并记录相应的元数据信息;以及根据前面所述的数据展现系统,其适于基于使用者输入的查询条件和显示参数,查询所述数据存储系统存储的数据并获取查询结果,然后显示在WEB前端。
根据本发明的又一方面,提供一种数据分析方法,其包括:从客户端和/或服务器中采集数据,所述采集的数据包含根据用户需求而设置的多个数据种类;将所述采集的数据进行提取、转换并传输;将所述传输的数据根据前面所述的数据存储方法进行存储、并记录相应的元数据信息;以及根据前面所述的数据展现方法,基于使用者输入的查询条件和显示参数,从所述存储的数据中获得查询结果并在WEB前端显示。
附图说明
在附图(其不一定是按比例绘制的)中,相似的附图标记可在不同的视图中描述相似的部件。具有不同字母后缀的相似附图标记可表示相似部件的不同示例。附图以示例而非限制的方式大体示出了本文中所讨论的各个实施例。
图1示出了根据本发明的一种实施方式的数据存储系统的结构示意图;
图2示出了根据本发明的一种实施方式的数据分析系统的结构示意图;以及
图3示出了根据本发明的一种实施方式的数据解析装置的结构示意图;
图4示出了根据本发明的一种实施方式的第二注册模块的结构示意图;
图5示出了根据本发明的一种实施方式的存储位置选择模块的结构示意图;
图6示出了根据本发明的一种实施方式的数据存储方法的流程图;
图7示出了本发明的对新的自定义属性进行注册的方法的一种实施例的流程图;
图8示出了本发明的为新的自定义属性选择用于存储的列的方法的一种实施例的流程图;
图9示出了根据本发明的一种实施方式的数据查询装置的结构示意图;
图10示出了根据本发明的一种实施方式的数据查询方法的流程图;
图11示出了根据本发明的一种实施方式的数据展现系统的结构示意图;
图12示出了根据本发明的一种实施方式的显示装置的显示界面的例子;
图13示出了根据本发明的一种实施方式的数据展现方法的流程图;以及
图14示出了根据本发明的一种实施方式的数据分析方法的流程图。
具体实施方式
下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
在本发明中,使用本发明的数据存储系统及方法存储数据或者使用本发明的数据分析系统及方法进行数据分析的公司或者人,统一称为“使用者”,而对于使用“使用者”的产品的人或者公司统一称为“用户”。
本发明的数据存储系统及方法主要针对大量数据的采集且所采集的数据中包含的数据种类会存在变化的情形。在这种情形下,对于解析出的新增加的数据种类的数据寻找到恰当的存储位置,从而才能实现对所采集的大量数据分门别类地有序存储。已有的方式是,对于数据种类的分类都已经事先设定好,该数据种类的存储位置也事先确定,当获取到新数据时,判断所述新数据是否属于已确定的数据种类,如果属于,则存储在指定的位置,如果不属于,则视为异常或错误而丢弃。这种存储方式不适应当采集的数据在后期有大量新数据种类出现的情形。这里数据种类泛指可以作为一组数据而存储在一起的划分方式。
图1示出了根据本发明的一种实施方式的数据存储系统的结构示意图。如图1所示,本发明的数据存储系统100包括数据获取装置110、数据解析装置120、元数据记录装置130、以及数据存储装置140。
其中,数据获取装置110适于获取需要存储的数据。这里,所述需要存储的数据为从客户端或服务器侧所采集的数据经过转换、处理后需要进行存储的数据,例如所述需要进行存储的数据已经被转换成JSON格式,由数据获取装置110所接收。另外,所述需要存储的数据会随时间而不断变化,例如在大数据分析中,会有大量数据不断地被采集。这里数据的变化不限于数据的数量的变化(增加或者删除),也包括数据种类的变化。例如当对新开发的应用APP进行统计时,最开始可能只需要统计注册人数,随着所述APP的不断推广,则可能增加对不同省份注册所述APP的人数的统计,还可能增加对注册所述APP的人数中男女性别的统计等等,这时数据种类就从注册人数进一步细分出按地域划分的人数、以及按性别划分的人数两个数据种类。在不同的阶段,根据不同的需求,可能会改变(包括增加和删除)对不同种类的数据的采集,在这种情况下,采集的数据种类改变时,对应的存储也要求相应地发生改变。
所述需要存储的数据根据需要可以被分为多个类别,例如可以被分为第一类别和第二类别。例如,在数据分析中,将所采集的数据分为事件类别和用户类别两大类别。这里并不限定划分两个类别,可以根据需要不划分类别、或者划分为三个以上的类别等等。
每个类别中还可以进一步包含一个或多个子类别,以对各个类别进行具体的区分,例如,对于新开发的购买产品的应用APP,其事件类别可以进一步分为启动应用事件、注册会员事件、浏览产品事件、购买产品事件、绑定银行卡事件等具体事件这些子类别。
每个子类别可以分别具有多种属性,所述属性可以包括预置属性和/或自定义属性。每种属性包含属性名及属性值,每种属性的属性值的数据类型都只能是一种数据类型,而不能为两种或两种以上的数据类型,且数据类型是固定不变的,例如,本发明的数据类型可以包括数字类型(numerical)、字符串类型(string)、日期类型(data)、日期时间类型(datatime)、布尔类型(boolean)、以及由字符串集合而形成的复合类型(List)等等。例如,对于“购买产品”事件的一个事件属性“设备类型”,其属性值只能为“苹果”、“三星”、“华为”等字符串,如果所采集到的该属性的属性值为“12”这样一个数字,则该“12”的属性值则被视为异常或错误。
所述预置属性是某一数据类别下所有子类别都共同包含的属性,其被预先设定好,例如其对应的属性值的数据类型以及存储位置都会预先在元数据记录装置130中记录好,不能再被改变。例如,对于事件这一类别下的所有具体事件(即子类别),如果都需要获取购买者使用的设备制造商、设备型号、省份、城市等属性的数据,则将这些属性都可以设置为预置属性,这样,每当采集事件类别有关的数据时,对于所有具体事件,都会采集这些属性的数据。
自定义属性,是用户自己根据需要设置的,既可以在程序安装前就设置好,也可以在程序安装之后再设置。对于在程序安装前设置好的自定义属性,其对应的的数据类型、以及存储位置都已经事先确定(即后面提及的元数据信息已经事先记录好)。在程序安装之后,可以根据需要添加、修改、或者删除自定义属性,从而增加了程序的灵活性。对于程序安装之后设置的自定义属性,并没有事先做很多限制,例如并不限制其属性值对应的数据类型、以及存储位置。对于每个自定义属性,其属性值的数据类型由第一次该自定义属性的属性值的数据类型确定,一旦确定了数据类型,如果采集到的该自定义属性的属性值为其它数据类型,则视为异常而被抛弃。而自定义属性的属性值的存储位置从数据存储装置140中的可用存储空间中进行选择,在选定存储位置后,则该自定义属性的所有属性值都存储在该存储位置。这样,可以将各类别下各个子类别的数据按照属性而存储在不同的存储位置。对于自定义属性,例如在“买入黄金”这一事件中,“商品名称”、“店铺名称”、“商品类型”、“商品价格”等都可以被设置为自定义属性。
由于自定义属性的设置的灵活性,使得可以根据需求在任何时候对子类别的属性进行设置,从而使得能够采集到想要的数据或者将数据进行想要的划分。
同样地,本发明的数据类别、以及数据类别中的子类别也可以根据需要添加、删除。
由于本发明的数据类别、子类别、子类别的属性可能根据需要而变化(添加或者删除),从而采集到的数据也会发生变化,对于这些基于类别、子类别、子类别的属性等被划分成的诸多种类的数据如何有序地进行存储决定着能否充分利用所采集的数据,例如对于新出现的自定义属性的存储位置的确定、对于已确定存储位置的自定义属性的不断增加的属性值的存储等等都非常重要。
由于数据获取装置110获取的数据可能具有不同的类别、子类别、属性等等特征,为了对这些数据进行有序的存储,需要先由数据解析装置120对这些数据进行解析,例如解析出这些数据的特征:类别、子类别、属性(预置属性和自定义属性)等等,然后根据这些数据的特征,确定其在数据存储装置140中的存储位置,并在元数据记录装置130中将数据的特征及存储位置这些信息记录成为元数据信息,这样,对于以后具有同样特征的数据则可以根据元数据记录装置130中记录的相关的元数据信息,即可知道存储在数据存储装置140中的相应位置。关于数据解析装置120将在后面结合例子详细说明。
其中,元数据记录装置130可以是服务器中的存储设备,主要是用来存储元数据信息。元数据记录装置130可以根据数据的类别而分成多个记录单元,例如,当数据类别包含第一类别和第二类别时,可以将与第一类别数据有关的元数据信息记录在第一记录单元中,将与第二类别数据有关的元数据信息记录在第二记录单元中。这样,也方便对不同类别的数据的元数据信息的查找。当然,本发明不限定记录单元的划分,元数据记录装置130也可以整体作为一个记录单元。另外,元数据信息可以包括不同类别的数据的元数据信息,还可以包括不同类别的元数据之间的关系的元数据信息,还可以包括关于数据映射关系的元数据信息等,本发明并不对此进行限定,可以根据需要采用适合的方式。例如,对于不同类别的元数据记录可以通过一个或多个元数据表进行描述,多个元数据表之间相互关联。
数据存储装置140可以由多种存储设备来实现,当存储大量数据时,也可以由服务器来实现,例如存储服务器、Vertica数据库服务器。如前面所述,当需要存储的数据包含多个类别时,可以将不同的类别分别存储在数据存储装置140中的不同存储单元,例如,当存在两种类别的数据时,可以将第一类别数据存储在第一存储单元,将第二类别数据存储在第二存储单元中,这样从类别上将数据分别存放,也方便后续的查询。这里,存储单元可以是数据存储装置140中的不同的内部磁盘空间,也可以一个磁盘空间中不同部分,本发明对此并不做任何限定。
下面,以数据分析为例具体介绍本发明的数据存储系统。但需要说明的是,本发明并不限于用于数据分析这一领域,其可以适用于任何需要对存在新的数据种类产生的大量数据进行存储的情形。
数据分析是指基于大规模数据而做出的统计和分析。在数据分析过程中需要采集大量的数据并对其进行统计、分析,其中会涉及大量数据的存储。数据分析可以根据不同的标准进行划分,通常可以包括用于追踪或记录用户行为或业务过程的事件分析;用于分析一个多步骤(包括至少两个以上步骤)过程中每一步的转化与流失情况的漏斗分析;用来分析用户参与情况/活跃程度的留存分析;和分析用户对产品的依赖程度的回访频率分析等等,本发明并不限于数据分析的类型,可以包括所述的这些数据分析类型中的一种或多种,也可以包括除上面所列数据分析类型之外的其它数据分析类型。
图2示出了根据本发明的一种实施方式的数据分析系统的结构示意图。如图2所示,本发明的数据分析系统200包括数据采集系统230、数据传输系统240、数据存储系统100、以及数据展现系统260。
其中,数据采集系统230适于从客户端210和/或服务器220侧采集数据。通常,数据采集系统230从客户端210和/或服务器220侧的后端、或者前端和后端采集数据(一般只从前端采集数据容易导致采集到的数据不全面),可以通过多种方式来实现:
第一种方式是批量方式采集数据,即一次导入一批数据。通常是在客户端或服务器中将一段时间的数据按照规定的数据格式写在一个文件中,然后将写好数据的文件上传至数据采集系统230,数据采集系统对数据格式、内容进行校验,如果没有问题,则交付数据传输系统240进行处理;
第二种方式是通过在客户端或服务器中的LogAgent实时采集数据。LogAgent是独立运行的进程,对指定目录中的日志文件进行追踪(Tail),将追踪到的内容发送至数据采集系统230;
第三种方式是通过客户端210和服务器220侧的SDK实时采集数据,然后由SDK将采集到的数据发送至数据采集系统230。
通常,在不同的设备上可能会安装不同的SDK。例如,在使用IOS操作系统或安卓操作系统的客户端210上安装Android/IOS的SDK,在使用PC机的客户端210和服务器220上安装Java/PHP/Python语言的SDK、在Web端安装JS语言的SDK。在实际中,数据采集系统230可能通过这几种SDK同时获取数据。
例如,Java/PHP/Python语言开发的SDK主要用来获取PC机端的数据,在后端处理一个业务逻辑(比如用户购买行为)后,发送一条事件有关的数据记录(例如track记录,这里track表示这个记录与事件有关)给数据采集系统230;在用户发生注册或登录行为时,将注册前的匿名id与真实id关联,发送一条数据记录(例如track_signup记录,这里track_signup表示这个记录既与事件有关也与用户属性有关)给数据采集系统230;在获知了用户的属性(比如年龄或性别)时,发送一条用户属性有关的数据记录(例如profile记录,这里profile记录表示这个记录与用户属性有关)给数据采集系统230。
JS(Javascript)语言的SDK主要用来获得Web前端的用户行为的数据。例如,当用户打开页面加载完成后触发一条事件有关的track请求,该请求内容包括页面URL等;当用户点击广告的时候触发另一条事件有关的track请求,内容包括页面URL、广告id、展示位置等;当用户的鼠标放到页面某个元素上时开始计时,鼠标离开的时候触发又一条事件有关的track请求,内容包括悬停的元素的id,鼠标悬停时间等等。在track请求被触发后,该track请求会携带请求内容被传送至数据采集系统230,在数据采集系统230形成一条track记录。
Android/iOS的SDK主要用来获得移动端的用户行为的数据。例如,当移动端用户打开应用App时发送一条track记录至数据采集系统230;当用户使用某些功能时触发一条track记录并传送至数据采集系统230等等。本发明的数据采集系统230可以通过上述任何一种或者多种方式采集数据,但本发明并不限定采用上述几种方式,也可以采用除上述方式之外的其它方式采集数据。
在数据被采集前可以事先根据被采集的数据的特色及使用者的需求而将数据划分成不同的类别(type),例如,划分成事件(event)和用户(User)两个类别。对于被采集的数据记录,其中都会包含表明类别的数据,例如,用“type”类型字段来表明数据类别,而对于事件(Event)类别的数据,“type”字段的取值设置为“track”,而对于用户类别的数据,则“type”字段的取值可以“profile_”开头,表示是用户概况(Profile),通常包括一个或多个用户属性,例如年龄、性别、喜好等等,例如profile_set表示直接设置一个用户概况profile。至于如何表明数据类别,并不限定上面例子所述的表示方式,可以根据需要和喜好进行设定。需要说明的是,这里是以数据类别包含事件和用户两大类别为例进行说明,实际不限于两大类别,可以包含更多的类别或者只包含一个类别。另外,关于两大类别的划分也不限于按照事件和用户进行划分。
为了进一步地对数据进行更精细地统计分析,对所划分的每个类别可以再进一步地划分出多个子类别,例如,对于事件(event)类别,可以根据事件本身的性质划分为不同的具体事件(即子类别),例如对于电商平台,可以包含:访问首页、搜索商品、浏览商品、用户注册、提交订单等多个具体事件,通过具体事件的划分可以将事件有关的数据进一步细分。对于所采集的有关事件的数据记录中,都会包含表明事件子类别的数据,例如可以用字段“event”后面的名称表明当前的具体事件;对于用户类别的数据,每个新的用户即为一个子类别,例如可以通过为每个用户创建的ID来表明,例如在用户未注册前,为其分配一个匿名ID,在注册后为其分配一个真实ID,而且可以将同一用户的匿名ID与真实ID关联起来。用户类别的数据可能会体现在事件中,也有可能不体现在事件中。
另外,对于每一具体事件可以具有不同的属性(property),通过属性的划分又可以将每个具体事件进一步细分,从而实现对数据的更为精细的划分。例如对于“浏览商品”这一事件可以包括商品名称、商品类别、店铺名称等多种属性。例如,其在数据记录中可以用“properties”属性字段表明。而对于每一属性还可以进一步细分成预置属性和自定义属性。例如,对于预置属性,在其属性名字段前放置“$”表明该属性为预置属性。而在属性名字段前没有放置“$”表明该属性为自定义属性。
虽然被采集的数据可能具有上述一种或者多种特征,但数据采集系统230在采集到数据后,并不对数据特征进行解析,但也会对数据做一些处理,供后续装置(例如数据传输装置240)使用,这些都是本领域技术人员所熟知的,例如通过Nginx对所述采集到的数据进行解压缩和协议解析,写入本地的Nginx日志文件中等等。
可选地,数据采集系统230还可以有其它的实现方式,例如,对于前面第一种数据采集方式,数据采集系统230可以包括在客户端或服务器中实现的部分功能,即,将一段时间的数据按照规定的数据格式写在一个文件中并上传;对于第二种数据采集方式,数据采集系统230可以包括LogAgent以及存储数据的文件;对于第三种数据采集方式,数据采集系统230可以包括设置于客户端或服务器侧的SDK。本发明并不限定数据采集系统230的实现方式,只要能够实现本发明的数据采集功能的数据采集系统230都可以用于本发明。
下面给出一个基于Java SDK撰写的电商客户的“浏览商品”事件的数据接入代码:
通过上述代码,采集如下数据:用户使用设备的操作系统、操作系统的具体版本、用户所在省份、城市、商品名称、商品类别、店铺名称,并且通过“track”表明这组数据是关于一个事件的数据。
上述代码只是一个例子,实际中,可以根据用户的需要通过put语句设置任何字段以采集想要的数据。
而且,由于本发明数据采集系统230可以采集用户服务端和业务数据库的数据,而不是前端JS/APP SDK记录的数据,因此,采集的数据相比于百度统计工具、友盟数据统计工具更加全面、可靠。另外,由于本发明的数据分析系统可以完全安装在用户侧,而不是用于分析用户数据的第三方平台,因此,用户可以安全地将自己的核心数据接入本发明的数据采集系统230,这样,一方面解决了用户数据安全问题,另一方面保障采集的数据更全面、更真实。
数据传输系统240适于对数据采集系统230所采集到的数据进行提取、转换并传输。例如数据传输系统240监控Nginx日志文件(针对前面数据采集系统230中提及的一个例子),对其进行解析并格式化,例如格式化成JSON格式,然后对其进行协议封装,例如按照Kafka协议进行封装,然后传输给数据存储系统100。
数据存储系统100如前所述,适于对从数据传输系统240接收的数据进行解析、存储,后面将进一步详细说明。
数据展现系统260主要适于基于使用者输入的查询条件和显示参数,获取对应的数据分析结果并在WEB前端进行显示。这里,所述查询条件与所述数据存储系统中存储的数据种类相对应,例如,在数据存储系统100中存储有关于“买入黄金”事件的数据(例如买入黄金的重量、次数累积、买黄金的人的年龄等等),那么在显示系统中就会存在关于与“买入黄金”对应的查询条件,例如“买入黄金”的总次数、总重量、不同年龄的人“买入黄金”的总次数等等查询条件。
所述数据展现系统260可以包括显示装置和查询装置等,其中所述显示装置适于接收使用者输入查询条件和显示参数。所述查询装置适于根据所述所述查询条件和显示参数从数据存储系统100中获取查询结果,然后由所述显示装置将数据结果显示给所述使用者。这些可以通过现有技术来实现(这里将不具体说明),也可以通过本发明后面所述的实施方式来实现,具体见后面关于数据展现系统260的描述。另外,可选地,所述查询装置也可以通过本发明后面描述的所述数据查询装置900来实现。另外,在上述描述中,使用者输入查询条件和显示参数的方式可以有多种方式,可以是直接输入关键词,也可以是从预定的选择菜单中的选项中选定。
下面以数据分析为例详细说明本发明的数据存储系统100。
如前面所述,数据获取装置110获取的数据并不是直接从客户端或者服务器侧采集到的数据,而是被采集到的数据经过提取、转换等处理后的需要存储的数据。另外,数据会不断地被采集,因此,会不断地有需要存储的数据产生。
例如,数据获取模块110获取电商平台关于“浏览商品”这一事件的数据如下(其以JSON格式给出):
在上面的数据中,表明数据类别的字段“type”的取值为“track”,所以该组数据记录的类别是事件(Event)类别。表明具体事件的字段“event”的取值“ViewProduct”,所以该组数据记录的具体事件为“浏览商品”。另外,其中还包含了很多属性方面的数据,分别列在字段“properties”下面,即,
$manufacture:用户所使用设备的制造商;
$model:用户所使用设备的具体型号;
$os:用户所使用设备的操作系统;
$os_version:用户所使用设备的操作系统版本;
$app_version:用户所使用的APP的版本;
$wifi:这条事件发生时,用户是否在使用wifi;
$ip:用户使用设备的IP;
$province、$city:省、市;
$screen_width、$screen_height:屏幕的宽和高;
product_id、product_name、product_classify、product_price:跟商品相关的一些具体属性。
其中,以$开头的各个属性都为预置属性,不以$开头的各个属性product_id、product_name、product_classify、product_price都是自定义属性。
上述是以事件为例进行说明的,对于用户类别,同样地,也可以包括预置属性和自定义属性。
另外,在上述JSON数据中还可以包含有其它一些相关信息,例如,
distinct_id:类型是字符串,表明对用户的标识,对未登录用户,可以填充设备标识,cookieID等,对于登录用户,则应该填充注册帐号;这里的例子,我们假设是一个未注册用户,所以填充的是一个设备编号;通过这个属性可以将事件类别的数据与用户类别的数据联系起来。
time:类型是数字,表明事件发生的实际时间戳,精确到毫秒。
虽然数据获取装置110所接收到的需要存储的数据有上述多种划分,但数据获取装置110并不进行解析,只是将这些数据接收过来并进行一些简单的处理。之后,数据解析装置120对数据获取装置110所接收到的需要存储的数据进行解析,解析出类别、子类别、属性等具体数据。
可选地,数据解析装置120,如图3所示,可以包括:第一解析模块123、第一注册模块121、以及第二注册模块122。
例如对于上面所获得的关于“浏览商品”这一事件的数据,数据解析装置120对其解析的过程如下:
第一解析模块123对数据的特征进行如下的解析:
第一,解析出数据的类别。例如,在数据分析中,根据数据获取装置110所获取的JSON数据中的类别(即“type”)字段的取值,判断这组数据是事件event数据还是用户数据。如上所述,当类别字段的取值为track时表示是事件类别,当以profile_开头时表示是用户类别。
第二,第一解析模块123解析各子类别。例如,对于数据分析,在解析出数据类别之后,解析其所包含的事件event或用户的具体名称。当数据类别为事件类别时,通过其后的字段“event”解析出具体事件的名称。当数据类别为用户类别时,通过用户的标识distinct_id解析出不同的用户。
对于每一子类别都会被分配有一个唯一的子类别标识符ID,以方便对其进行记录、查询、和存储等。所有的子类别名称及对应的子类别标识符ID都会被存储在缓存器125(例如Cache)中,也会在元数据记录模块130记录元数据信息。
第一解析模块123在解析出各个子类别名称之后,会在缓存器中查找该子类别名称,如果能查到该子类别名称具有相应的子类别标识号ID,那么表明该子类别曾经出现过,已经为其分配了子类别标识号ID;如果未查到该子类别名称具有相应的子类别标识号ID,那么表明该子类别是新的子类别,需要由第一注册模块121为其分配一个子类别标识号ID。在本发明中,每一个新的事件子类别都需要第一注册模块121为其分配一个新的子类别标识号ID,而对于用户子类别,可以由系统为每个用户自动设置的设备编号(例如前面的distinct_id)或者用户的登录号作为子类别标识号,则不需要由第一注册模块121再专门为其分配一个子类别标识号。
第一注册模块121适于对所述需要存储的数据包含的新的子类别进行注册,为其分配子类别标识号ID。在为所述新的子类别分配了子类别标识号ID之后,会将该子类别名称及其对应的子类别标识号ID在元数据记录装置130中记录相应的元数据信息,另外,也可以同时存储在缓存器125中。
例如,对于上述“浏览商品”事件的JSON数据而言,第一解析模块123解析“event”字段,获得事件名称“浏览商品”,然后在缓存器125中通过事件名称查询该“浏览商品”事件的ID号,如果查到,则接下来解析该“浏览商品”事件的属性。如果没有查到,则由第一注册模块122为其分配一个ID号,然后将该“浏览商品”事件名称及ID号存储到缓存器125中,并在元数据记录装置130中记录该“浏览商品”事件的元数据信息,该元数据信息包括“浏览商品”事件名称及ID号,例如,记录在元数据记录装置130的事件描述元数据表(即event_define表,在后面关于元数据信息的的描述中有具体例子)中。
上述例子涉及的是具体事件,对于具体用户,用户标识符User_ID(和/或distinct_id)如前所述会由系统自动生成,而对于每个用户概况(profile)(即“type”字段中以“profile_”开头的数据记录,其中包含一个或多个用户属性properities)与所述具体事件一样,都会被分配一个标识符ID,例如,对于新的用户概况,采用与所述具体事件同样的方式,为其新分配一个Event_profile_ID(可以将具体用户概况(profile)看作一种特殊的具体事件Event),并在元数据记录模块130中记录相应的元数据信息,例如记录在元数据记录模块130中属性描述元数据表(即property_define表)中。例如,“type”字段中以“profile_”开头的数据记录可以包括“profile_set”(用于直接设置一个用户概况)、“profile_increment”(用于增加或减少一个用户的某个数字类型的用户概况Profile,例如用户年龄等)、“profile_delete”(用于删除一个用户的整个概况Profile)、“profile_append”(用于向某个用户的某个数组类型的用户属性添加一个或者多个值,例如向用户喜好这一用户属性中添加“桔子”、“柚子”等值)等等,它们都会被分别分配一个Event_profile_ID。
对于已有的具体事件和已有的具体用户,已经具有其Event_ID、Event_profile_ID、和User_ID(或distinct_id),而且在元数据记录模块130中的event_define表和property_define表中已经分别记录了已有具体事件和事件名称及对应的ID、已有具体用户的用户名称与对应的ID。
第三,第一解析模块123解析子类别的属性,所述属性如上所述可以包括预置属性和自定义属性。
具体地,第一解析模块123解析所述子类别包含的一个或多个属性的属性类别、属性名、以及属性值的数据类型。
首先,第一解析模块123判断所述属性是否是预置属性,如果是预置属性且不是用户概况中的属性,另外,在缓存器125(例如cache)或元数据记录装置130中(例如属性描述元数据表(property_define)中,后面将具体说明)查询到已经事先记录的与该预置属性对应的元数据信息(通常如果设置缓存器125,则先查缓存器125,再查元数据记录装置130;如果不设置缓存器125,则直接查元数据记录装置130),则返回该预置属性已有。如果判断是预置属性但在元数据记录装置130却没有其对应的元数据信息,则视为该数据异常。
例如,在上述的“浏览商品”事件的数据中,通过判断每个属性的属性名字段前是否具有符号“$”,其event_id是否为-1(例如将所有的预置属性的event_id都统一设置为-1,这样在元数据记录装置130中记载的元数据表中可容易识别预置属性),即可确定是否是预置属性。例如下表给出预置属性的元数据表的一个例子:
上表中,记录了事件标识号event_id,属性英文名Name、属性中文名Cname、在Vertica数据库中存储的列名分别为Vertica_name和Vertica_name_redundancy,数据类型Data_type、Is_value_mapping表明存储的是否是映射了的数值。由于上表中各数据都是存储的映射值,所以Vertica_name_redundancy是空值,具体原因在后面有详细解释说明。不同的数据类型用不同的数字1-6中之一表示。从上表中的Event_id的取值为-1和Name中前面带$字符可知,上述各数据都是预置属性。
在属性不包含预置属性而只包含自定义属性的情形下,则省去上述第一解析模块123对预置属性的解析过程。
如果第一解析模块123判断所述属性是自定义属性,首先,判断该自定义属性是否已经存储过,即,判断是已有的自定义属性还是新的自定义属性。例如,可以从缓存器125中查找该自定义属性的属性名称及所属子类别的标识号ID,如果存在,则表明是已有的自定义属性,否则为新的自定义属性。对于新的自定义属性,需要由第二注册模块122对其进行注册。
对于已有的自定义属性,其在元数据记录装置130中记录有包含其在数据存储装置140中的存储位置和存储的数据类型的元数据信息(例如在元数据表Property_define表中)。这时,第一解析模块123只需确定该自定义属性的当前属性值的数据类型是否与所记录的元数据信息中的数据类型相匹配,如果不匹配,则视为错误,抛弃该自定义属性的当前属性值;如果匹配,则将该自定义属性当前属性值与其原有的元数据信息(包括事件名、属性名、属性描述(property_define)表信息)组装在一起形成一个属性记录(property_record),依据该属性记录,将该自定义属性的当前属性值存储在数据存储装置140中的相应位置(例如Vertica表中的某行某列)。例如,这个过程可以通过如下代码来实现:
#此处假设自定义属性已经注册成功/或已经存在无需注册,若注册失败,则已抛异常。
在实际中,可能会出现对自定义属性进行注册但注册失败的情形,对于这种情形,会与已经注册成功的自定义属性或者已经存在的自定义属性一样继续进行属性值的数据类型是否与元数据信息中记录的数据类型一致的判断,而判断结果肯定是不匹配,这时再将该自定义属性的属性值作为错误而抛弃,而不是在注册未成功时就将该自定义属性的属性值抛弃。
对于自定义属性的属性值的数据类型可以事先设定都包含哪些数据类型,而对于不被包含的数据类型,则视为错误或异常。例如,本发明的数据分析的例子中可以设定允许的数据类型包括如下类型(如上述例子所示,不同的数据类型可以用不同的数字表示):
·number:数字。
·String:字符串,UTF8编码,最大长度255字节。
·Date:日期类型。
·Datetime:日期时间类型,精确到毫秒。
·Boolean:真/假(true/false)。
·List:复合类型,是字符串的集合。
上述描述中,以数据解析装置120包含缓存器125为例进行说明的,实际上,本发明的数据解析装置120可以不使用缓存器125(在不使用缓存器125的情形下,则直接查询元数据记录装置130),或者可以将缓存器125设置于元数据记录装置130中,或者可以在第一解析模块123、第一注册装置121、第二注册装置122中分别设置有各自的缓存器125,本发明对此不进行限定。缓存器125的设置可以将经常被存储的类别、子类别、属性类型等信息存储在缓存器125中,从而加快查询效率。
第二注册模块122适于对所述子类别包含的新的自定义属性进行注册,确定各新的自定义属性的属性值的数据类型及在数据存储装置140中的存储位置等等。相应地,由第二注册模块122为该新的自定义属性所确定的存储位置和存储的数据类型等信息在元数据记录装置130中进行记录。
可选地,第二注册模块122,如图4所示,可以包括存储单元选择模块1221、存储空间使用状态获取模块1222、和存储位置选择模块1223。
其中,所述存储单元选择模块1221适于根据所述需要存储的数据的类别确定在所述数据存储装置140中的存储单元。例如,当数据分析中存在事件Event和用户两种数据类别时,可以将两个类别在所述数据存储装置140中存储在不同的存储单元,即分别单独存储,例如存储在两个数据表中,这样可以使数据存储更为有序、也便于查询。另外,在不同类别的数据中,可能存在着相同的属性名,但因为存储在不同的存储单元(例如数据表)中,即使相同的属性名对应的属性值的数据类型不同,也不会互相影响。但在本发明中,在每个存储单元中,相同的属性名的属性值必须具有相同的数据类型,否则容易出现错误。
可选地,可以根据每个子类别的子类别标识号ID来确定存储在所述数据存储装置140中的哪个存储单元中。因为子类别被分配了子类别标识号ID之后,会在元数据记录装置130中记录相应的元数据信息,即,将子类别名称、以及分配的子类别标识号ID记录在元数据记录装置130中,例如,对于“浏览商品”这一事件的事件名及已分配的子类别标识号(即Event_id号)记录在元数据记录装置130中的event_define表中,通过查所记录的元数据信息,即可通过子类别标识号得知其所属类别,知道所属类别,则可确定存储在所述数据存储装置140中的哪个存储单元。
存储空间使用状态获取模块1222适于从所述存储单元选择模块1221确定的存储单元的追踪器中获取该存储单元的存储空间使用状态。
对于数据存储装置140,为了更好地管理其存储空间,及时获知哪些存储区域已被占用、哪些存储区域未被占用,可以设置有使用状态追踪器。可选地,对整个全部存储空间设置一个使用状态追踪器;可选地,对于数据存储装置140包含的每个存储单元分别设置一个使用状态追踪器,这样可以更为快速、准确地获得各个存储单元的使用状态。例如当事件Event的每个自定义属性的属性值都存储在数据存储装置140中的Vertica的Event表的一列中、而用户概况Profile的每个自定义属性的属性值都存储在数据存储装置140中的Vertica的User表的一列中时,这里Event表可以视为第一存储单元141、User表可以视为第二存储单元142。这时,可以设置第一追踪器143及时追踪Event表的列使用状态,设置第二追踪器144及时追踪User表的列使用状态。当新的自定义属性是某一具体事件的属性时,存储空间使用状态获取模块1222则需要从第一跟踪器143获取Event表的列使用状态信息;当新的自定义属性是某一用户概况的属性时,存储空间使用状态获取模块1222则需要从第二跟踪器144获取User表的列使用状态信息。
存储位置选择模块1223适于确定各自定义属性在所述存储空间中的存储位置。在存储单元选择模块1221为一自定义属性选定了存储单元、存储空间使用状态获取模块1222获取的被选定的存储单元的存储空间使用状态之后,可以知道所述存储单元的存储空间中的哪些区域已经被使用,哪些区域未被使用,存储位置选择模块1223可以从未被使用的存储区域中选择适于存储所述自定义属性的属性值的位置。
例如,第一类别(例如事件)数据存储在第一存储单元141的第一数据表(例如Vertica的Event表)中,在所述第一数据表中,所述第一类别数据的子类别(例如具体事件的Event_id)按行在第一数据表中存储,所述子类别的各自定义属性的属性值按列在第一数据表中存储;第二类别(例如用户)数据存储在第二存储单元142的第二数据表(例如Vertica的User表)中,所述第二类别数据的子类别(例如用户User_id)按行在第二数据表中存储,所述子类别的各自定义属性的属性值按列在第二数据表中存储。
在事件(Event)数据被存储于Vertica的Event表中、且各自定义属性按列分别存储于Event表的列中的情形下,当某一新的自定义属性需要在Event表中选择一列或两列或多列存储时,则可以根据存储空间使用状态获取模块1222获得的Event表的列使用状态,从Event表中选择可以使用的一列或两列或多列用于存储所述新的自定义属性。在所述新的自定义属性被确定了存储的列之后,所有该自定义属性的后来的属性值都存储在该确定的列中,从而方便管理不同属性的数据。实际上,不同的具体事件可能具有相同的自定义属性,但只要是属于事件类别的数据,相同自定义属性的属性值都被存在相同的列中。而对于不同的具体事件,可以按行存储在Vertica中的Event表中。这样,每当接收到一个自定义属性的属性值时,就可以按照其所属的具体事件(子类别)从元数据表Event_define找到Event_id,然后再根据Event_id在元数据表Property_define表中找到该Event_id的所有属性,如果需要存储的自定义属性已经存储过,则元数据表Property_define表中会记录该自定义属性的属性值在Vertical的Event表中的存储位置。同理,对于用户User表也可以采用同样的方式存储用户自定义属性的属性值。
在第二注册模块122为各自定义属性确定存储位置之后,在元数据记录装置130中记录各自定义属性的元数据信息。例如,对于某一具体事件的新的自定义属性,将数据解析装置120解析出的具体事件的Event_id、属性名称、属性值的存储位置(例如Vertica中某一列或两列)等信息以元数据的形式记录在元数据记录装置130中的property_define表中。
可选地,在上述例子给出的情形下,存储位置选择模块1223,如图5所示,还可以包括可用列计算模块510、判断模块520、列添加模块530、和列选择模块560。后面主要以事件Event为例进行说明,其同样适用于用户。
其中,可用列计算模块510适于基于如下公式计算第一数据表(例如Vertica中的Event表)的可用列CA:
所有列CT-(所有被使用过的列CU-优先列CP)-同一子类别的所有属性使用过的列CTU
其中,对于所有列,是指Event表中的所有可以用于存储自定义属性的列。通常每一列都有一个名称,如果这些列的名称都符合本发明的命名规范,就都视为符合本发明的要求列。所述命名规范,例如,对于每一列按如下中的一种命名规范命名:str_{数字}(字符串)、bin_{数字}(二进制型,只有LIST会用到此类型的列)、int_{数字}(数字)、和super_{数字}分别表示用于存储属性值的数据类型为字符串的字符串列、用于存储属性值的数据类型为LIST的列、用于存储属性值的数据类型为数字的数字列、用于存储属性值为除LIST之外的数据类型,且存储的数据为数字的列。通过{数字}中“数字”的不同,可以区分出多个不同的对应列。例如,int_1,int_2,str_0,bin_0,var_field_22都是符合该命名规范的列名,而int_A就不是符合本发明命名规范的列,不计入所有列的范围中。这里假设不包含预置属性的情形,如果包含预置属性,所有列是指Event表中的所有可以用于存储属性(包括自定义属性和预置属性,但是预置属性的列已经被预先设定,即已经被使用)的列。
所述优先列CP为自定义属性的属性名相同和属性值的数据类型相同的自定义属性使用过的列。通常,在为自定义属性选择使用的列时,这些列会被优先选择使用。例如,对于“搜索商品”这一事件,其包含的自定义属性“商品名称”在第一次出现时,在Event表中为其选择了列C1用于存储其属性值,那么之后在存储“浏览商品”这一事件的自定义属性时,如果其中也包含自定义属性“商品名称”,则“浏览商品”这一事件的自定义属性“商品名称”的属性值就可以优先选择存储在列C1中,当然,前提是二者属性名相同,对应的属性值的数据类型也相同,如果属性名相同,而数据类型不同,那么在解析该属性值则不会被存储。
在计算可用列时,由上面公式可知,需要从所有列中去除已经被使用过的列,因为一个列一旦已经被使用了,就说明该列已经被指定存储某一自定义属性的属性值,而该自定义属性的属性值一旦被指定存储在所述列,那么之后的所有该自定义属性的属性值就一直都被存储在该列。但在所有被使用过的列中,具有相同属性名且属性值的数据类型相同的优先列是可以被使用的,而且可以被优先使用,因此,在所有被使用过的列CU中还需要去除优先列CP。另外,在同一张存储表中,在同一子类别(例如同一具体事件Event)下不能存在同名属性,所以,在同一子类别下的所有属性已经使用过的列需要从所有列中去除,这样得到用于计算自定义属性的可用列的上述公式。
判断模块520适于判断所述可用列计算模块510计算得到的可用列是否能够用于存储所述自定义属性的属性值。对于每个自定义属性,其属性值的数据类型都是确定的,那么,在为每个自定义属性选择存储的列时,需要选择能够存储符合属性值的数据类型的列。例如,对于自定义属性“商品名称”,其属性值的数据类型为字符串,那么,在为其选择存储的列时,需要在所有用于存储字符串的列中进行选择,例如,在没有被使用的命名为str_30至str_50的列中选择。但实际中,一方面,可能存在所有可用列为零,即没有供使用的列的情况,另一方面,即使存在可用列,但可用列用于存储的数据类型都与该自定义属性的属性值的数据类型不匹配。在这种情形下,则列添加模块530需要在所述数据表中为该自定义属性增加预定数量的列,所述增加的列是根据所述自定义属性的属性值的特征增加的。例如,该自定义属性的属性值的数据类型是字符串,那么增加的列就是一个字符串列,而不是数字列或者其它数据类型的列。通常,在增加了可用列之后,可用列计算模块510会重新计算可用列,然后由判断模块520再进行判断,这样的过程可能会被重复,这是考虑到在多线程运行的情形下,新增的列可能会被其它线程抢占。
列选择模块560适于从所有可用列中选定列用于存储当前子类别的所述自定义属性的属性值。
可用列计算模块510计算得到的可用列可能多于自定义属性所需的列数,或者在判断模块判断没有满足要求的可用列的情形下新增了预定数量的列(但在多线程同时运行的情形下,可能同时会为数个自定义属性增加需要的列,因此新增加的列也可能会有多个),无论在任何情形下,都需要列选择模块560从可用列中选定用于存储该自定义属性的列,例如按顺序依次选择、或者倒序选择、或者随机选择等等均可。
可选地,列选择模块560可以通过如下方式来选定列:
将所有可用列与所述优先列的交集中的第一列开始的预定数量的列确定为用于存储所述自定义属性。例如,当需要一列时,则可以选择所有可用列与所述优先列的交集中按照名字字典序的第一列。例如,int_0,int_1,int_10,int_11就是一个字典序的排列,从中取第一个,即取int_0列。
在所有可用列与所述优先列无交集时,将所有可用列去除所述优先列之后的剩余列中的第一列开始的预定数量的列确定为用于存储所述自定义属性。例如,如所有可用列为CA=[int_0,int_1,int_2,str_0,str_1,str_2],优先列为CP=[int_0,str_0],那么CA–CP=[int_1,int_2,str_1,str_2],按字典序排列,得到['int_1','int_2','str_1','str_2'],当所需的列是数字列,则取第一个,即int_1。
本发明并不限定列选择模块560为自定义属性选择存储的列的方式,任何可以实现这样的目的的方式均可以用于本发明。
对于不同的自定义属性的属性值,根据属性值的数据类型,其所需要的存储列数可能会有所不同。例如,当属性值为数字(Number)、日期(Date)、日期时间(Datetime)、或布尔(Boolean)等的数据类型时,可以使用一个数字类型(INT)的列进行存储。对于复合类型(LIST)的数据,可以使用一个二进制数据(VARBINARY)列进行存储。例如,对于一个LIST=[“apple”,“pear”,“melon”],其是三个字符串的集合。其中假设Apple的映射值为1,pear的映射值为2,melon的映射值为3,那么1,2,3分别转为4字节存储,再拼接在一起,拼接后是一段二进制数据,用二进制表示如下:
“0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0010
0000 0000 0000 0000 0000 0000 0000 0011”
上述二进制数据可以存储在一个VARBINARY列中。
当属性值为字符串型的数据类型时,由于字符串通常都比较长,因此可以根据情况选择一列或两列来存储具有字符串型属性值的自定义属性。
具体地,当某一个很长的字符串重复很多次,则没有必要总存储该字符串,而是可以采用一个数字来代表这个字符串进行存储,同时,在元数据记录模块130中用元数据记录这个数字与这个字符串的映射关系。这样可以节省存储空间及存储效率、而且可以提高查询效率。
对于属性值的数据类型为字符串型的自定义属性,根据其稳定性状态确定选择几列来存储。自定义属性的稳定性状态表明其属性值的存储方式是否为已经确定的存储状态,其可以分为不稳定状态UNSTABLE和稳定状态STABLE。
稳定状态STABLE是指已经确定采用映射Mapping方式的存储状态(简称M状态)、或采用按非映射No-mapping方式的存储状态(简称为N状态)。
M---表示按映射Mapping方式的存储状态,是指对于自定义属性的属性值,只需一个INT型的主列存储与该属性值的字符串对应的数字,而不需要存储字符串,数字与字符串之间的映射关系(后面有具体例子)等以元数据的形式存储在元数据记录模块130中。
N---表示按非映射No-mapping方式的存储状态,是指对于自定义属性的属性值,只需一个可变字符串(Varchar)型的主列存储该属性值的字符串。
不稳定状态UNSTABLE是指对于自定义属性的属性值,还没有确定采用映射Mapping方式存储或者采用非映射No-mapping方式存储,其状态可能会随时变化。例如,对于数据类型为字符串的新的自定义属性,通常一开始按不稳定状态(简称U状态)进行存储,即,通常采用一个INT型主列存储与字符串对应的数字,采用一个Varchar型的冗余列存储字符串,并记录对应的元数据信息,例如记录在元数据记录装置中的Property_define表中。但其稳定性状态会随时间而变化,具体可以通过如下方式判定是否需要更换其稳定性状态:
例如当导入该自定义属性数据一段时间(例如5-10分钟),就可以统计出该自定义属性的字符串取值,例如一个取值为“苹果”,例如重复5000次,一个取值是“梨”,例如重复1万次。
对该自定义属性的取值进行去重处理,即计算:
UNIQE(不同取值的个数)/ALL(所有取值的个数)
如果上述计算得到的比值越小,则表明重复率越高。例如设定去重率10%为预定阈值,如果所述比值小于10%,则不记录字符串,而是记录与该字符串对应的数字,即采用非稳定状态且映射(mapping)方式的存储状态,简称UM状态,那么所述自定义属性的属性值的存储状态从U状态转变成UM。如果重复率不高于所述预定阈值,则记录字符串,而不采用Mapping方式,这时存储状态从U状态转变成UN状态。由此可知,自定义属性的不稳定状态随着时间的增加,可能会不断变化,例如,还可能从UM状态变为UN状态,或者反过来。这种状态的转换可能会存在着反复,但随着统计时间的增长,会逐渐趋于稳定。在自定义属性的数据统计到一预定时间段之后,可以根据上述的计算比值判定其存储状态是否已经稳定为No-mapping方式或者Mapping方式。例如,如果所述计算比值一直高于所述预定阈值,则表明存储状态一直保持在UN状态,这时可以将其稳定性状态由不稳定状态转变为稳定状态且按No-mapping方式存储属性值,即前面所述的N状态,同理,如果一直保持在UM状态,可以将其稳定性状态由不稳定状态转变为稳定状态且按Mapping方式存储属性值,即前面所述的M状态。另外,需要说明的是,在自定义属性的稳定性状态变为稳定状态之后,该自定义属性的属性值的存储状态也就相应地确定下来,不再会变化。
其中,UM状态按Mapping状态(M状态)存储,即选择一个INT型的主列存储与该属性的属性值对应的数字,无需冗余列。
UN状态按No-mapping状态存储,则选择一Varchar型的主列存储该属性的字符串类型的属性值即可,无需其它列。
另外,说明的是,每当自定义属性的状态发生变化时,其在元数据记录模块130中记录的与其稳定性状态对应的元数据信息也要相应地进行修改。
第一解析模块123对已有的自定义属性进行解析时,会解析其稳定性状态,从而确定其存储位置。从上面所述可知,正常的存储状态包括M、N、U、UM、UN,如果解析出MN、UMN状态,则视为异常。其中,
MN状态表示既处于Mapping状态又处于No-mapping状态。
UMN状态表示处于不稳定状态、且Mapping、且No-mapping状态。
由上述可知,在判断出了自定义属性的属性值的数据类型之后,即可以确定该自定义属性的属性值需要一列或者两列进行存储。上述列选择模块560可以基于此从可用列中选定一列或两列用于存储所述自定义属性的属性值。
在对自定义属性的属性值选定了存储位置后,则完成对该自定义属性的注册。在使用缓存器125(例如,Cache)的情形下,将所述自定义属性的元数据信息记录到缓存器125中以更新Cache125,并将列使用状态记录到对应数据表的追踪器,更新所述追踪器。
另外,对于预置属性,其属于稳定状态,不存在非稳定状态。由于对于某个预置属性可以事先知道mapping和no-mapping哪种存储状态更适合,所以一般都提前确定其中一种,并将相应的元数据事先记录在元数据记录模块130中。比如,对于“省份”这个预置属性字段,取值有限(省份个数一共几十个,所以去重后取值个数一定是几十,与总体数据的比值一定很小),使用mapping存储状态更合适。再比如,对于“姓名”这个预置属性字段,取值的重复度小,则事先确定使用no-mapping存储状态。
下面举例说明元数据记录装置130中所记录的元数据信息。
对应于事件(Event)类别与用户类别,元数据记录装置130包含第一记录单元,记录例如第一元数据表,事件描述元数据表(即event_define表),用于记录Event类别有关的元数据信息;和第二记录单元,记录例如第二元数据表,属性描述元数据表(即Property_define表),用于记录用户类别有关的元数据信息。例如,
1)event_define表结构,其描述event基本信息。
上表中“类型”是指对应的字段的数据类型。
2)Property_define表结构,描述property(属性)基本信息,
上表中“类型”是指对应的字段的数据类型。
在Property_define表同时存储事件的属性以及用户的概况(profile),所以Property_define表也可以称为用户的profile_define表。
以上两个表主要是属性值与Vertica数据表之间的列映射有关的元数据表结构。
在上述Property_define表结构中,vertica_name和vertica_name_redundancy记录的就是属性对应的在vertica数据表中的列,除了字符串(STRING)类型之外,其他类型都只需要记录vertica_name。
对于STRING类型,当处于不稳定状态的时候,同时记录vertica_name和vertica_name_redundancy,在处于稳定状态之后则选择其中一列作为vertica_name的最终值,而将vertica_name_redundancy置为空(NULL)。
下面通过一个实例具体说明本发明。例如,
数据获取装置110获取如下一条事件信息:
{
"type":"track",
"time":1443693643000,
"properties":{
"product_name":"xx_gold",
"price":100
},
"event":"BuyGold",
"distinct_id":"test_id"
}
假设这条数据中的“买入黄金”事件(“BuyGold”)及其属性都是新的,即,在以前从未出现过,那么会导致新增子类别及其属性的元数据记录。
由上述这条数据可知:
新增事件:BuyGold
新增属性如下表所示:
属性名 | 属性值的数据类型 |
price | NUMBER数字 |
product_name | STRING字符串 |
其中,product_name的属性值是字符串,而且是从未出现过的属性名,所以product_name将会以不稳定状态存储,也就是会占用两列存储,即,vertica_name和vertica_name_redundancy将都会有值。
因此,数据解析装置120解析上述关于“BuyGold”事件的JSON数据,会对新增事件“BuyGold”及其属性值分别进行注册,并会在元数据记录装置130中基于前面所述的Event_define表结构记录如下面所示的关于“BuyGold”事件的元数据信息:
event_define表(事件描述元数据表)
从上表可知,该新增“BuyGold”事件已经被分配了id为5的子类别标识符。
同时,也会在元数据记录装置130中基于前面所述的Property_define表结构记录“BuyGold”事件中各个属性的property_define表的元数据信息(即完成各属性的注册之后),如下图所示(为了看起来方便,下表将行以列的形式进行显示):
property_define表(属性描述元数据表)
如上表所示可知,Vertica_name对应的列为int-14,其被选定存储新增属性price。而新增属性product_name被选择存储在两列,即,Vertica_name为int-13的列,Vertica_name_redundancy为str_2的列。
在新增事件BuyGold及其属性分别在元数据记录装置130中记录了对应的event_define表和property_define表之后,再有关于BuyGold的属性price和product_name的数据需要被存储时,只需在event_define表中查找到BuyGold的event_id是5,然后,在property_define里按照event_id=5筛选,即可得到price和product_name两个属性的元数据信息,从而可知price和product_name两个属性分别被存储在Vertica数据表中的哪行哪列,因此,可以很容易地将相同属性的数据存储在Vertica数据表中,具体地,在上述property_define表中查找到price的存储的列Vertica_name为int-14,则可知buygold这个事件的属性price存储在Vertica中int-14列中;在上述property_define表中查找到product_name的存储的列Vertica_name为int-13,Vertica_name_redundancy为str_2,则可知product_name这个属性在Vertica中列int-13和str_2的列存储,而对于每一条新来的数据,即使是关于已经出现过的相同的事件(例如“买入黄金”事件)或用户,在Vertica数据表中都会用新的一行进行存储。
另外,从上表中可以看到product_name的data_type是2,此处2代表STRING,当数据类型为字符串时,Vertica_name列和vertica_name_redundancy列均不为空(也可以知道,这时处于不稳定状态,且采用No-mapping的存储状态,即UN状态)。当数据类型为除了字符串之外的其它类型时,则只需要记录vertica_name列即可,这里price属性的属性值是数字类型的数据,因此只记录了vertica_name列,而vertica_name_redundancy列为空。
下表中,给出在Vertica中存储的一个Event数据表结构的例子:
在上述Event数据表结构中,“time”和“user_id”是每一条数据被采集时就携带的数据,“month_id”、“week_id”、“date”是基于“time”而得出之后存储在Vertica中的。
在该Vertica中的Event数据表中存储的一条具体Event_id=1的数据记录如下所示:
实际上上述数据位于在Event表中的一行(即Event_id=1的行),而每行表示在Event表中各属性的各列,这里为了显示方便,将其以行的形式列了出来。对于Event_id=1的一条数据在Vertica数据表中只占了其中的4个数字列int_0、int_1、int_10、int_11,和12个super_{数字}列,即super_0至super_11列,其余列并没有使用。
其对应于元数据记录装置130中的event_define表中的如下元数据信息:
以及对应于元数据记录装置130中的property_define表中的如下元数据信息:
根据上述event_define表中的元数据信息可知,上述Vertica中记录的event_id=1的数据是关于“浏览商品”事件的一条数据,但在Vertica中并不存储“浏览商品”事件的事件名,而只存储该事件的event_id。
根据上述property_define表中的元数据信息可知,“浏览商品”这一事件(表中以event_id=1表示浏览商品事件)的属性信息包括:Vertica中的数字列int_0对应着属性“商品名称”,数值为48;Vertica中的数字列int_1对应着属性“店铺名称”,数值为15;Vertica中的数字列int_10对应着属性“商品类型”,数值为10;Vertica中的数字列int_11对应着属性“商品价格”,数值为8000000;以此类推,可以依次知道Vertica中的super_0至super_11列所对应的属性名。在上述property_define表中,event_id=1对应的属性是自定义属性,而event_id=-1对应的属性是预置属性。当然,对于由数字代表字符串的情形,在元数据记录装置130中还会存储各数字与相应字符串的对应表,例如基于如下的属性原数据表结构来建立属性原数据表:
Field | Type | Null | Key | Default | Extra |
id | Int(11) | No | PRI | NULL | auto_increment |
raw_value | Varchar(255) | Yes | MUL | NULL |
例如,在元数据记录装置130中记录如下属性原数据表(数字与字符串的对应表):
id | raw_value |
7157 | /manual/android_sdk.htm |
14320 | /manual/b2b_homepage_case_core_measure.htm |
13927 | /manual/b2b_homepage_case_data_feed.htm |
而上述的event_define表和property_define表是通过解析JSON数据而记录的。例如,
由上述property_define表中记录的元数据得知int_11中记录的是“商品价格”(即ProductPrice)的存储列,在Vertica中的存储值是8000000,由于内部是按照各商品价格乘经1000后存储的,所以实际值是8000000/1000=8000。而产生这条元数据信息的最初的json数据如下:
当然,上述JSON数据会产生上述的event_define表以及property_define表。
由上述例子可知,一条数据是如何存储在Vertica中的Event表和User表的,而每条数据的特征以及在Vertica中的存储位置都是记录在元数据记录装置130中,而不需要存储在Vertica中,因此,可以节约存储空间,而且使大量数据有序地存储并非常便于查询。
利用本发明的数据存储系统100,当新来的一组数据中存在新的具体事件event时,会自动地在Vertica中新增一行存储该具体事件Event,且将其包含的属性的属性值存储在相应的列(如果是已有的属性),如果新的事件event中包含了新的属性,也会自动地在Vertica中对每一新的属性新增一列或两列用于存储对应的属性值。从而可以灵活地存储新增数据,在数据分析中,方便用户采集并获得自己所需的数据。当然不仅仅针对具体事件,同样适用于每个用户,概括的讲,适用于任何类别、子类别、及属性类型。
根据本发明的另一方面,还提供一种数据存储方法600,如图6所示,本发明的数据存储方法600起始于步骤610,在步骤610中,获取需要存储的数据。所述需要存储的数据为从客户端或服务器侧所采集的数据、经过转换、处理后的数据,例如所述需要进行存储的数据已经被转换成JSON格式。另外,所述需要存储的数据会随时间而不断变化,这里数据的变化不限于数据的数量的变化(增加、删除、或者改变),也包括数据种类的变化。具体参见前面的描述,这里不再重复描述。
所述需要存储的数据具有多个特征,例如所属的类别、子类别、属性类型、属性值的数据类型等等。通常,所述需要存储的数据根据需要可以被分为多个类别,例如可以被分为第一类别和第二类别,例如,在数据分析中,将所采集的数据分为事件类别和用户类别两大类别。这里并不限定划分两个类别,可以根据需要不划分类别、或者划分为三个以上的类别等等。
每个类别中还可以进一步包含一个或多个子类别,以对各个类别进行具体的区分。每个子类别可以分别具有多种属性,所述属性包括预置属性和/或自定义属性。每种属性具有属性名及属性值。每种属性的属性值的数据类型都是固定不变的,例如,数据类型可以包括数字类型、字符串类型、日期类型、日期时间类型、布尔类型、以及由字符串集合而形成的复合类型等等。另外,任何一种属性的属性值的数据类型都只能是一种类型,而不能为两种或两种以上的数据类型。
接下来,在步骤620,对所述需要存储的数据进行解析,获得所述需要存储的数据的特征并确定其存储位置。所述数据的特征,例如所属类别、子类别、属性类型(预置属性和自定义属性)、属性值的数据类型等等,然后根据这些数据的特征,确定其存储位置。例如,当所述需要存储的数据存储到Vertica的数据表中时,则可以根据数据的特征确定存储在数据表的哪一行和哪一列中。
可选地,在步骤620中,可以进一步包括步骤:解析所述需要存储的数据中包含的新的子类别和已有子类别、所述子类别中的新的自定义属性和已有的自定义属性。对于已有自定义属性和新的自定义属性的数据解析方式会有所不同。已有自定义属性表示曾经出现过,已经记录过元数据信息,在元数据信息中记载了将其属性值存储的位置,这种情况下,只需判断所述已有自定义属性的属性值的数据类型与元数据信息中记录的数据类型是否一致,如果一致则按照所记录的元数据信息存储在对应存储位置,如果不一致,而视为异常。
而对于新的自定义属性,则需要为其新建立元数据信息,为其属性值选择存储的位置。对于已有子类别和新的子类别都有可能包含新的自定义属性。为新的自定义属性建立元数据信息的过程实际上也是为新的自定义属性确定存储位置的过程,这个过程也称为自定义属性注册过程。确定其存储位置时,需要根据所述新的自定义属性所属的子类别确定在数据表中行的位置。而对于每个子类别都会被分配一个子类别标识符,这个过程可以称为子类别的注册过程。对于已有的子类别,已经被分配了子类别标识符,因此,其元数据信息已经被记录,通过查找子类别名称即可获取其子类别标识符。对于新的子类别,需要为其新分配一个子类别标识符,然后将该新的子类别名称、子类别标识符等信息记录到元数据信息中,如前面给出的Event_define表的例子所示。
图7示出了本发明的对新的自定义属性进行注册的方法700的一种实施例的流程图。如图7所示,在对新的自定义属性的注册时,在步骤710,根据所述新的自定义属性所属的数据类别确定要存储的对应数据表。如前面所述,当存在多个类别的数据时,为了方便、有序地对数据进行存储,不同类别的数据被存储在不同的数据表(例如不同的Vertica数据表)中。每个自定义属性有其数据类别,根据其数据类别即可确定其要被存储的数据表。例如Event事件类别就被存储在Vertica中的Event数据表中,用户类别被存储在Vertica中的用户(User)数据表中。
接下来,在步骤720,获取所述对应数据表的列使用状态。在为所述新的自定义属性选择存储的列之前,需要先了解对应数据表中哪些列已经被占用,哪些列可以供存储使用。对于存储单元,通常设置有存储单元使用状态追踪器来追踪存储单元的存储空间使用状态,例如,对于每一数据表,可以设置及时追踪数据表中的列使用状态的追踪器,因此,可以从一数据表的追踪器获取相应数据表的列使用状态。本发明并不限定追踪器的设置形式,例如可以多个存储单元共用一个追踪器,也可以每个存储单元单设一个追踪器。
接下来,在步骤730,根据所述对应数据表的列使用状态和所述自定义属性的属性值的数据类型,确定所述自定义属性在所述对应数据表中存储的列。从前面所述可知,对于不同的数据类型的数据,为其选择的存储列的数目会有不同,比如,当属性值为数字(Number)、日期(Date)、日期时间(Datetime)、或布尔数(Boolean)等的数据类型时,可以使用一个数字类型(INT)的列进行存储。对于复合类型(LIST)的数据,可以使用一个VARBINARY列进行存储。而对于属性值为字符串时,会根据其稳定性状态而有U、M、N、UM、UN等多种存储状态,在不同的存储状态下选择的存储列数目也会有所不同,这里就不重复描述了。
当所述对应数据表的列使用状态为存在可用的存储列时,还需要根据所述属性值的数据类型来进一步判断哪些列适合存储所述新的自定义属性的属性值。由于本发明所允许的数据类型、以及自定义属性都可以提前设定,所以可以根据这些情况事先设置具有尽可能多列的数据表而且所述多个列中有多个分别用于存储不同数据类型的属性值的列,从而当有新的自定义属性出现时,对应存储的数据表中有足够多的列供选择。
可选地,步骤730还可以采用另外一种方式来确定所述自定义属性在所述对应数据表中存储的列。如图8所示,在步骤731,基于如下公式计算所述对应数据表的可用列CA:
CA=所有列CT-(所有被使用过的列CU-优先列CP)-所述子类别的所有自定义属性使用过的列CTU
其中,所述优先列CP为与要存储的自定义属性的属性名和属性值的数据类型都相同的、已经存在的且被其它事件所采用的列。
接下来,在步骤732,判断所述计算得到的可用列是否能够用于存储所述自定义属性的属性值;
接下来,在步骤733,在判断所述可用列中不能用于存储所述自定义属性的属性值的列的情形下,在所述对应数据表中增加预定数量的列;以及
接下来,在步骤735,从所有可用列中选定列用于存储所述自定义属性的属性值。具体地,从所有可用列中选定列可以有多种方式,例如按顺序依次选择、或者倒序选择、或者随机选择等等均可。可选地,还可以通过如下方式选择:
将所有可用列CA与所述优先列CP的交集中的第一列开始的预定数量的列确定为用于存储所述自定义属性,例如从交集中的数字列依字典序列排列后选择第一列。
在所有可用列CA与所述优先列CP不存在交集的情形下,将所有可用列CA去除所述优先列CP之后的剩余列中的第一列开始的预定数量的列确定为用于存储所述自定义属性,例如从剩余列中的数字列中依字典序列排列后选择第一列。
关于上述各步骤的具体实施方式,在前面有关图5的描述中进行了详细描述,这里就不再重复描述。
以上结合实施例详细地描述步骤620的具体操作,在步骤620通过对数据解析、为新的自定义属性等需要存储的数据选择用于存储其数值(即属性值)的列之后,接下来,在步骤630,记录所述需要存储的数据的元数据信息。所述元数据信息包括所述需要存储的数据的特征及存储位置。例如,根据所述存储的数据的特征,可以将其元数据信息按类别分别存储在不同的表中,例如,将作为子类别的具体事件的ID及事件名等相关信息存储在事件描述元数据表Event_define中,将具体事件包含的各属性的相关信息及各属性的属性值的存储位置存储在属性描述元数据表property_define中。通过分别存储,可以方便存储及查询。
接下来,在步骤640,基于所记录的元数据信息,将所述解析出的数据存储在相应的存储位置。由于在元数据信息中记录了不同数据的存储位置,因此通过找到匹配的元数据信息,即可知需要存储的数据的存储位置,而无需每次需要存储时,在存储设备中搜索空闲的存储区域,然后随机地存储在一个位置,这也不方便后续对所存储的数据的查询。在本发明中,当需要存储的数据包含多个类别时,可以将不同的类别分开存储在不同的存储单元,例如,存储在不同的Vertica数据表中。
在前面的描述中,主要是针对用户可以自行设定并能修改的自定义属性进行的说明,实际上子类别中还可以包括预先设置的预置属性,并且事先记录了所述预置属性的元数据信息,所述预置属性的元数据信息包括将所述预置属性具有的属性值存储的指定存储位置以及属性值的数据类型。在这种情形下,在对所述需要存储的数据进行解析的步骤620中还要包括解析所述子类别的预置属性、以及所述预置属性的属性值的数据类型,确定所述预置属性的属性值的存储位置。由于预置属性已经预先设置了存储位置,因些,只需从元数据中查找该预置属性的元数据信息,找到相应的存储位置即可,但前提时,需要判断所述预置属性的属性值的数据类型是否与元数据信息中记录的数据类型一致,如果一致,则存储在所指定的存储位置,如果不一致,则视为异常而抛弃对应的属性值。
根据本发明的另一方面,还提供一种数据查询装置900,如图9所示,本发明的数据查询装置900包括第一接收模块910、第二解析模块920、查询机制建立模块930、第一查询模块940、第一发送模块950、以及第一存储模块955。
其中,第一接收模块910适于接收来自WEB前端261的查询请求。所述查询请求包含一个或多个查询条件和一个或多个显示参数。这里,第一接收模块910可以直接接收来自WEB前端261的查询请求,也可以是经WEB服务器接收来自WEB前端261的查询请求。当用户在WEB前端261的界面中从预定的查询条件和预定的显示参数中选定查询条件和显示参数之后,则会产生一个查询请求,例如所述查询请求可以是包含URL的查询请求,所述查询条件和显示参数包含于URL中。下面就是一个包含URL的查询请求的例子(当使用者在WEB前端261的界面中选定按天、按性别查看厦门市2015年10月5日和6日两天“买入黄金”的“黄金总重量”):
http://test.sensorsdata.cn/segmentation/{"measures":[{"event_name":"BuyGold","aggregator":"SUM","field":"event.BuyGold.GoldWeight"}],"unit":"day","filter":{"conditions":[{"field":"event.BuyGold.$city","function":"equal","params":["厦门市"]}]},"by_fields":["user.Gender"],"bucket_params":{},"to_date":"2015-10-06","from_date":"2015-10-05","use_cache":true,"request_id":1449629311232}
即,需要解析上述URL中的如下参数:
第二解析模块920适于基于数据存储系统100的元数据记录装置130中记录的元数据信息解析所述查询请求,获得解析结果。如前面关于数据存储系统100的部分的描述可知,对于存储在数据存储装置140中的数据都在元数据记录装置130中记录有对应的元数据信息,该元数据信息表明了所存储的数据的特征及在数据存储装置140中的存储位置。所述元数据信息如前面所给出的“事件描述元数据表(event_define表)”和“属性描述元数据表(property_define表)”等等。通过基于查询请求中的查询条件和显示参数中包含的字段,查找元数据信息,从而获知对数据存储装置40中哪些存储位置的数据进行查询的信息。可选地,进一步地,可以基于所获知的存储位置的信息构建查询机制片段,例如构建SQL查询机制中包含的SQL语句片段。
例如,对于前面所述的例子,基于URL中包含的每一个字段,查找元数据记录装置130中记录的“事件描述元数据表(event_define表)”和“属性描述元数据表(property_define表)”、以及字段与数字的映射表(前面未示出)等等,构建相应的SQL语句片段。
例如,解析Event_name以及相关属性,创建一个新Event表,赋予该新Event表以别名a,针对这个新Event表,创建了事件id属性,日期属性,购买城市属性,购买设备型号属性等,例如构建形成如下SQL语句片段:
"a"."event_id","a"."date","a"."int_2"等等
同时,创建一个新User表,赋予该新User表以别名b,针对这个新User表,创建用户id属性,用户性别属性,用户年龄属性,用户注册时间属性等,例如构建形成如下SQL语句片段:
"b"."id","b"."int_5"等等。
上面构建出来的SQL语句片段存储在存储模块955中,供后续查询机制建立模块930构建查询机制。需要说明的是,上述构建的SQL语句片段不一定之后都能用上,有可能只会用上其中的一部分。
上述过程可以通过如下代码来实现:
eventTable=createEventTable(alias,event);
userTable=createUserTable(alias);
解析上述URL,当发现“指标”、“过滤条件”、“筛选条件”中任何一个涉及到用户属性时,需要将上述构建的新Event表以及新User表结合在一起,形成结果表。
另外,解析上述URL中的时间过滤条件,构建形成如下SQL语句片段:
"a"."date"BETWEEN'2015-10-05'AND'2015-10-06'
解析上述URL中的事件分析过滤条件,即“厦门市”这一过滤条件,构建形成如下SQL语句片段:
"a"."int_2"in(189)
其中,上述SQL语句片段中,"a"."int_2"是在前面构建出来的,in(189)是解析事件分析过滤条件新构建形成的。
解析上述URL中的指标参数,构建如下关于指标列的SQL语句片断:
COALESCE(SUM("a"."int_28"),0)AS num。
同样,上述构建的述SQL语句片段也都存储在存储模块955中备用。
在构建出上述SQL语句片段之后,根据URL参数中包含的过滤条件、筛选条件等,构建在结果表中添加相应的列的SQL语句,例如,在上述例子中,
根据时间过滤条件,构建在结果表中添加时间列的SQL语句“SELECT'2015-10-05'AS unit”,这样在最终查询Vertica中的数据表而得到的结果表中会直接显示时间列,方便查看和区分。
同样,根据URL参数中包含的按性别查看的筛选条件,构建在结果表中添加相应的分组列的SQL语句“GROUP BY 1,2”。
同样,根据上述URL参数中包含的指标参数,构建在结果表中添加相应的分组列的SQL语句“SELECT COALESCE(SUM("a"."int_28"),0)AS num”。
以上实施例给出的解析方式是基于后续建立SQL查询语句进行的解析,如果所建立的查询机制不同,则可以采用不同的解析方式。
查询机制建立模块930适于基于第二解析模块920的解析结果建立查询机制。具体地,将第二解析模块920的解析结果进行组合构建出对数据存储装置中存储的数据的查询机制。例如,当选择使用SQL进行查询时,则基于所述解析结果构建SQL查询机制。
对于上述的例子,基于第二解析模块920解析URL参数而获得的SQL语句片段以及所确定的需要在结果表中添加的列,构建如下完整的SQL查询语句:
基于上述完整的SQL查询语句,就可以查询Vertica中所存储的数据了。上述完整的SQL查询语句存储在存储模块955中。每当接收到来自WEB前端261的查询请求,就会基于所述查询请求利用上述方法构建完整的SQL查询语句。
第一查询模块940适于根据所建立的查询机制查询数据存储系统100中的数据存储装置140中的数据,获得查询结果。这里的查询结果不限于直接从数据存储装置140中查询得到的数据,而且可以包括基于所述查询机制而对其中一部分或者全部数据进行一定的组合计算的结果,例如,当需要查询每天注册用户总数时,则查询结果是基于所查询到的每天注册的用户而计算得到的用户总数。
例如,如前面所述,所采集的数据最终存储在例如Vertica的Event表和User表。根据上述查询机制建立模块930所建立的完整的SQL查询语句可以查询Vertica的Event表和User表,获得相应的数据,并根据需要进行分组、按指标进行计算、按时间分别给出相应的查询结果,例如给出性别分别为男和女的查询结果、将在相应日期中所购买的黄金进行和运算得到黄金总重量等等。例如,上述例子进行查询得到如下查询结果:
2015-10-02 271
2015-10-03 303
所获得的查询结果可以暂时存储在第一存储模块955中。
第一发送模块950适于将所述查询结果发送给WEB前端261。可选地,第一发送模块950将所述查询结果以WEB前端261能够展现的格式进行重构,然后发送给WEB前端261。例如,对于上述例子所获得的查询结果,通过格式转换,转变成如下的格式:
{"series":["2015-10-02 00:00:00","2015-10-03 00:00:00"],
"rows":[{"values":[[271],[303]],"by_values":[]}],"num_rows":1}
然后,以上述格式将查询结果发送至WEB前端261。具体地,所述查询结果经WEB服务器发送至WEB前端261,或者所述查询结果先存储在WEB服务器的内存中,然后由WEB服务器发送至WEB前端261。
根据本发明的另一方面,还提供一种数据查询方法1000,其适于对按照前面所述的数据存储方法存储的数据进行查询,如图10所示,本发明的数据查询方法1000起始于步骤1010,在步骤1010,获取来自WEB前端的查询请求,所述查询请求包含一个或多个查询条件和一个或多个显示参数。例如所述查询请求可以是包含URL的查询请求,所述查询条件和显示参数包含于URL中。
接下来,在步骤1020,基于被存储的数据的元数据信息,解析所述查询请求中包含的查询条件和显示参数,获得解析结果。如前面关于数据存储系统100的部分的描述可知,对于存储在数据存储装置140中的数据都在元数据记录装置130中记录有对应的元数据信息,该元数据信息表明了所存储的数据的特征及在数据存储装置140中的存储位置。所述元数据信息如前面所给出的“事件描述元数据表(event_define表)”和“属性描述元数据表(property_define表)”等等。通过基于查询请求中的查询条件和显示参数中包含的字段,查找元数据信息,从而获知对数据存储装置140中哪些存储位置的数据进行查询的信息。可选地,进一步地,可以基于所获知的存储位置的信息构建查询机制片段,例如构建SQL查询机制中包含的SQL语句片段。所获知的信息或者所构建的查询机制片段存储在内存中,例如存储在WEB服务器的内存中。
接下来,在步骤1030,基于所述解析结果构建查询机制。具体地,将第二解析模块920的解析结果进行组合构建出对数据存储装置中存储的数据的查询机制。例如,当选择使用SQL进行查询时,则基于所述解析结果构建完整的查询SQL语句作为查询机制。
接下来,在步骤1040,基于所构建的查询机制查询所述存储的数据,获取查询结果。这里的查询结果不限于直接从数据存储装置140所存储的数据中查询得到的数据,而且可以包括基于所述查询机制而对其中一部分或者全部数据进行一定的组合计算的结果,例如,当需要查询每天注册用户总数时,则查询结果是基于所查询到的每天注册的用户而计算得到的用户总数。例如,当所构建的查询机制是SQL查询机制时,可以通过所构建的完整的查询SQL语句对所述存储的数据进行查询。
接下来,在步骤1050,将所述查询结果发送至所述WEB前端。可选地,将所述查询结果以WEB前端能够展现的格式进行重构,然后发送给WEB前端,例如可以将查询结果存储在WEB服务器的内存储器中,然后发送至WEB前端。
根据本发明的又一方面,提供一种数据展现系统260,如图11所示,本发明的数据展现系统260包括显示装置262、第二接收模块264、获取模块266、以及如前面所述的数据查询装置900。
其中,显示装置262位于WEB前端,适于接收使用者对查询条件和显示参数的输入、以及显示基于所述查询条件和显示参数所获得的查询结果。
第二接收模块264位于WEB服务器中,适于接收来自显示装置262的所述查询条件和显示参数,并传送至根据权利要求22-24中任何一项所述的数据查询装置900。
数据查询装置900如前面所述根据所述查询条件和显示参数,查询根据权利要求1-11所述的数据存储系统100中的数据存储装置140存储的数据,获得查询结果。
获取模块266位于WEB服务器中,适于从所述数据查询装置900中获取所述查询结果,并将所述查询结果发送至所述显示装置262进行显示。
可选地,所述数据展现系统260还可以包括轮询模块263和第二存储模块265。
其中,轮询模块263位于WEB服务器中,适于以预定时间间隔查询并获取数据存储系统100中的元数据记录装置130中记录的元数据信息,所述元数据信息中包含多个字段,所述字段为所述查询条件中的一个参数,例如可以是在所述WEB前端显示的事件名称、事件属性名称、或者用户属性名称等等。
所述预定时间间隔可以设置为每隔5秒钟、10秒钟、10分钟或者1小时等等。所述轮询模块263查询元数据记录装置130中记录的元数据信息,例如元数据表。当例如出现一个新的“注册”事件时,在元数据记录装置130的Event_define表中会记录有该新的事件的Event_id及事件名,如果该新的事件中的属性也是新的属性,那么在Property_define表中会记录有相应的新的属性的属性名(中文名称和/或英文名称)等信息。当轮询模块263获取元数据信息时,会将包含该新的事件及其新的属性在内的元数据信息都获取到,并存储在第二存储模块265中。这里,第二存储模块265可以是WEB服务器的内存储器。
当在显示装置262侧,使用者开始对查询条件进行选择时,会产生一个触发,该触发会被传送至WEB服务器侧,并被第二接收模块264接收到。例如,与所存储的数据对应的字段会以查询条件的参数的形式显示在显示装置的显示界面的各个选择框中,例如,在如图12所示的显示界面中包含多个选择框,例如“事件”的选择框,在“事件”选择框的下拉菜单中罗列有例如“买入黄金”、“卖出黄金”、“启动应用”等事件的字段作为查询条件。当使用者点击显示装置262界面中的选择框或者选择框旁的下拉菜单时,就会产生一个对查询条件和/或显示参数的选择的触发。
当第二接收模块264接收到来自显示装置264的这样的触发时,获取模块266会根据该触发,从第二存储模块265中获取所有字段并发送给显示装置264进行显示,将相应的字段显示在相应的选择框下。这样,当所有字段中包含了新的字段时,就可以相应地显示在选择框旁的下拉菜单中了。
实际上,显示装置262的界面中设置的选择框旁边的菜单中各选项也是通过同样的方式添加到菜单中的,只是很多字段在本发明的数据分析系统安装时,就已经添加到选择框旁边的菜单中了。
通过本发明的数据展现系统,一方面可以根据使用者选择的查询条件和显示参数快速地获得并展现查询结果,另一方面也可以将新增的字段及时、快速地告知WEB前端并在其中显示,而无需先在WEB前端进行配置然后再对应地在进行后端配置,这样可以实现显示字段从后端至前端的“一站式”直达显示的效果。
根据本发明的另一方面,提供一种数据展现方法。如图13所示,根据本发明的数据展现方法1300,起始于步骤1310,在步骤1310,接收来自于WEB前端的使用者输入的查询条件和显示参数,例如,使用者在图12中所示的界面中选择查询条件和显示参数之后,会传送至WEB服务器侧。
接下来,在步骤1320,根据所接收到的查询条件和显示参数,采用前面所述的数据查询方法,查询按照前面所述的数据存储方法存储的数据,获得查询结果。这部分内容在前面已经分别详细描述了,这里为了简便,不再重复描述。
接下来,在步骤1330,将所述查询结果发送至WEB前端进行展现。如前面所述,所述查询结果可以经WEB服务器发送至WEB前端进行显示。
可选地,本发明的数据展现方法1300还可以包括如下步骤:
在步骤1340,以预定时间间隔查询所述存储的数据的元数据信息,获取所有字段的元数据信息,所述字段为所述查询条件中的一个参数。
所述预定时间间隔可以设置为每隔5秒钟、10秒钟、10分钟或者1小时等等。例如以预定时间间隔查询对所存储的数据记录的元数据表,并获取所有字段的元数据信息。例如当元数据信息中包含有新的字段时,在Event_define表中会记录有新的“注册”事件字段的Event_id及事件名,如果该新的事件中的属性也是新的属性,那么在Property_define表中会记录有相应的新的属性的属性名(中文名称和/或英文名称)等信息。
在步骤1340中进行的查询是自动根据设置的预定时间间隔进行的,获得元数据信息,可以包含字段,也可以包含该字段有关的信息。
接下来,在步骤1350,将所有字段的元数据信息存储在WEB服务器的内存储器中。这样,当元数据信息中包含新的字段时,都一同被存储在WEB服务器的内存储器中了。
接下来,在步骤1360,基于来自所述WEB前端的对查询条件的选择的触发,从WEB服务器的内存储器中获取所述元数据信息中包含的所有字段。
当使用者点击显示在WEB前端的界面中设置的选择框旁边的菜单(在菜单中有多个查询条件或显示参数的选项)时,就触发了对查询条件和/或显示参数的选择,基于该触发,启动对WEB服务器的内存储器中的所有字段的获取。
接下来,在步骤1370,将获取的所有字段发送至WEB前端并显示在相应的选择框下。这样,当元数据信息中出现新的字段(包括事件和属性等的字段)时,就可以及时地展现在WEB前端的显示界面中,供使用者进行选择。
这里,步骤编号并不限定各步骤的先后顺序,实际中可能有的编号在后的步骤先执行,有的编号在前的步骤后执行。例如上述步骤1340~1370可以在上述步骤1310~1330前执行。
本发明的数据展现方法与前面所述的数据展现系统基本上是对应的,为了简洁,就不详细描述了。
根据本发明的又一方面,还提供一种数据分析方法1400,如图14所示,本发明的数据分析方法1400起始于步骤1410,在步骤1410,从客户端和/或服务器中采集数据,所述采集的数据的种类由使用者或者其技术人员设置,使用者可以根据要采集数据的产品本身的特色以及其需求,设置需要采集的数据种类,这里的数据种类包括数据类别、子类别、属性类型(自定义属性和预置属性)等各种划分出来的数据种类。
接下来,在步骤1420,将所述采集的数据进行提取、转换并传输。
接下来,在步骤1430,将所述传输的数据通过前面所述的数据存储方法记录元数据信息、并进行存储。所述的数据存储方法在前面已经详细描述了,这里不再重复描述。
接下来,在步骤1450,基于使用者选定的查询条件和显示参数,从所述存储的数据中获取对应的数据作为查询结果并显示,所述查询条件与存储的数据种类相对应,例如,当所述存储的数据中存储有“操作系统”有关的数据时,则在WEB前端显示的查询条件中对应地显示有“操作系统”这一事件属性的查询选项。当然,这里的查询条件并不一定与存储的数据种类完全一致,也可能是基于数据种类进行不同的组合而形成的一个新的查询选项,例如总次数、总重量等等。
关于本发明的数据分析方法在前面图2关于数据分析系统的描述中有详细的说明,二者基本上对应,为了简洁,这里不再重复描述。
利用本发明的数据分析系统和数据分析方法,能够保证从数据源采集的数据的安全性,因为本发明是私有布署在使用者自己一侧,所采集到的数据归使用者自己所有(即使布署在远程,但由于有自己的密码,他人也不会获得其数据),而不会被第三方所获得。在保证数据源的数据的安全的情况下,可以使本发明实现对数据源的数据的全面的采集,从而获得的数据更真实、更具有说服力。另外,本发明的数据存储系统及方法、数据查询装置及方法能够使数据有序、快速地存储,查询得更快捷,从而使得使用者在WEB前端能够非常快速地查看想要的结果。另外,由于本发明采集的是多维数据,从而能够实现精细化的多维分析。还有,使用者还可以根据需要从数据源侧或者数据采集系统侧修改所采集的数据的种类,例如增加新事件、新属性等,这样的新事件、新属性在WEB前端的对应显示不需要从WEB前端进行配置,而是可以直接根据数据源侧或者数据采集系统侧的修改对应地显示于WEB前端。
在本发明的上述描述中,关于各系统或装置中的模块的划分并不限定上面所述的划分,实际上可以根据需要进行划分更多的模块,或者将不同的模块进行组合,只要能够实现所述系统和装置的功能即可。例如,数据存储系统中的元数据记录装置可以不包含于数据存储系统中,而可以是独立于数据存储系统的一个单独的装置。另外,关于方法的步骤的划分也不限定前面所述的划分,实际上可以根据需要进行更多的划分或者将两个或更多的步骤合并成一个步骤,只要能够实现所述方法的功能即可。
需要说明的是,本发明的上述描述中,所述行和列并不对本发明有所限定,其可以互换。所述步骤的前后排列并不限定其执行顺序,其可以根据需要而调整。另外,第一和第二并不表明限定只有这两种,还有可能有第三、第四等等,或者只有第一,这里只是为了尽可能充分说明本发明的技术方案而以第一和第二进行了举例说明。另外,本发明并不对数据关于类别、子类别、属性等的划分级别进行限定,可以根据实际情况进行更少的级别划分或者列多的级别划分,而且划分的级别名称也不限于本发明的类别、子类别、属性等。
在此处所提供的说明书中,说明了大量具体细节。然而,能够理解,本发明的实施例可以在没有这些具体细节的情况下实践。在一些实例中,并未详细示出公知的方法、结构和技术,以便不模糊对本说明书的理解。
类似地,应当理解,为了精简本公开并帮助理解各个发明方面中的一个或多个,在上面对本发明的示例性实施例的描述中,本发明的各个特征有时被一起分组到单个实施例、图、或者对其的描述中。然而,并不应将该公开的方法解释成反映如下意图:即所要求保护的本发明要求比在每个权利要求中所明确记载的特征更多的特征。更确切地说,如下面的权利要求书所反映的那样,发明方面在于少于前面公开的单个实施例的所有特征。因此,遵循具体实施方式的权利要求书由此明确地并入该具体实施方式,其中每个权利要求本身都作为本发明的单独实施例。
本领域那些技术人员可以理解,可以对实施例中的设备中的模块进行自适应性地改变并且把它们设置在与该实施例不同的一个或多个设备中。可以把实施例中的模块或单元或组件组合成一个模块或单元或组件,以及此外可以把它们分成多个子模块或子单元或子组件。除了这样的特征和/或过程或者单元中的至少一些是相互排斥之外,可以采用任何组合对本说明书(包括伴随的权利要求、摘要和附图)中公开的所有特征以及如此公开的任何方法或者设备的所有过程或单元进行组合。除非另外明确陈述,本说明书(包括伴随的权利要求、摘要和附图)中公开的每个特征可以由提供相同、等同或相似目的的替代特征来代替。
此外,本领域的技术人员能够理解,尽管在此所述的一些实施例包括其它实施例中所包括的某些特征而不是其它特征,但是不同实施例的特征的组合意味着处于本发明的范围之内并且形成不同的实施例。例如,在下面的权利要求书中,所要求保护的实施例的任意之一都可以以任意的组合方式来使用。
本发明的各个部件实施例可以以硬件实现,或者以在一个或者多个处理器上运行的软件模块实现,或者以它们的组合实现。本领域的技术人员应当理解,可以在实践中使用微处理器或者数字信号处理器(DSP)来实现根据本发明实施例的浏览器客户端中的一些或者全部部件的一些或者全部功能。本发明还可以实现为用于执行这里所描述的方法的一部分或者全部的设备或者装置程序(例如,计算机程序和计算机程序产品)。这样的实现本发明的程序可以存储在计算机可读介质上,或者可以具有一个或者多个信号的形式。这样的信号可以从因特网网站上下载得到,或者在载体信号上提供,或者以任何其他形式提供。
应该注意的是上述实施例对本发明进行说明而不是对本发明进行限制,并且本领域技术人员在不脱离所附权利要求的范围的情况下可设计出替换实施例。在权利要求中,不应将位于括号之间的任何参考符号构造成对权利要求的限制。单词“包含”不排除存在未列在权利要求中的元件或步骤。位于元件之前的单词“一”或“一个”不排除存在多个这样的元件。本发明可以借助于包括有若干不同元件的硬件以及借助于适当编程的计算机来实现。在列举了若干装置的单元权利要求中,这些装置中的若干个可以是通过同一个硬件项来具体体现。单词第一、第二、以及第三等的使用不表示任何顺序。可将这些单词解释为名称。
Claims (34)
1.数据存储系统,适用于对不断采集的大量数据进行存储,且所述不断采集的数据存在着变化,其特征在于,所述采集的数据根据用户需求而设置有多个数据种类,且所述数据种类是根据用户需求的变化而可变化的,所述数据种类基于数据的特征而划分成多个数据种类,所述数据的特征包括数据类别、子类别、属性,其中所述类别包括一个或多个子类别,每个子类别分别具有一种或多种属性;所述数据存储系统包括:
数据获取装置,其适于获取需要存储的数据,所述需要存储的数据为从客户端或服务器侧不断采集的数据在经过转换和处理后而需要进行存储的数据;
数据解析装置,其适于将所述数据获取装置获取的所述需要存储的数据进行解析,获得所述需要存储的数据的特征并根据所述需要存储的数据的特征确定所述需要存储的数据的存储位置;
元数据记录装置,其适于记录所述需要存储的数据的元数据信息,所述元数据信息包括所述需要存储的数据的特征及存储位置;以及
数据存储装置,其适于基于所述元数据记录装置记录的元数据信息,将所述数据解析装置解析出的数据存储在相应的存储位置。
2.根据权利要求1所述的系统,其中,
所述需要存储的数据类别包括第一类别和第二类别,所述属性包括自定义属性,每种属性具有属性名及属性值;
所述数据存储装置包括存储所述第一类别数据的第一存储单元和存储所述第二类别数据的第二存储单元;
所述数据解析装置解析所述需要存储的数据的类别、子类别、以及所述子类别具有的自定义属性,确定各自定义属性的属性值的数据类型以及在所述数据存储装置中的存储位置;
在所述数据存储装置的第一存储单元和第二存储单元中,具有相同属性名和属性值的数据类型相同的自定义属性存储在相同存储位置,且所述存储位置所存储的属性值的数据类型由第一次存储的属性值的数据类型确定。
3.根据权利要求2所述的系统,其中,
所述属性值的数据类型包括:数字类型、字符串类型、日期类型、日期时间类型、布尔类型、以及由字符串集合而形成的复合类型。
4.根据权利要求2所述的系统,其中,
所述数据解析装置包括:
第一解析模块,其适于解析所述需要存储的数据中包含的新的子类别和已有子类别、所述新的子类别和已有子类别中的新的自定义属性和已有的自定义属性、各自定义属性的属性值的数据类型;对于已有子类别中的已有自定义属性,判断其属性值的数据类型与元数据信息中记录的所述已有自定义属性的属性值的数据类型是否一致,如果一致则按照元数据记录装置记录的元数据信息存储在所述数据存储装置中的存储位置,如果不一致,则视为异常;
第一注册模块,其适于对所述需要存储的数据包含的新的子类别进行注册,为其分配子类别标识号;以及
第二注册模块,其适于对所述子类别包含的新的自定义属性进行注册,为其建立元数据信息,确定各新的自定义属性的属性值在所述数据存储装置中的存储位置。
5.根据权利要求4所述的系统,其中,
所述第一存储单元包括第一追踪器,所述第一追踪器用于获得所述第一存储单元的存储空间的使用状态;
所述第二存储单元包括第二追踪器,所述第二追踪器用于获得所述第二存储单元的存储空间的使用状态;
所述第二注册模块包括:
存储单元选择模块,其适于根据所述需要存储的数据的类别确定在所述数据存储装置中的存储单元;
存储空间使用状态获取模块,其适于从所述存储单元选择模块确定的存储单元的追踪器中获取在该存储单元的存储空间使用状态;和
存储位置选择模块,其适于根据所述存储空间使用状态获取模块获取的所述存储单元的存储空间使用状态,确定各自定义属性在所述存储空间中的存储位置以及存储的数据类型。
6.根据权利要求5所述的系统,其中,
所述第一类别数据存储在所述第一存储单元的第一数据表中,所述第一类别数据的子类别按行在第一数据表中存储,所述第一类别数据的子类别的各自定义属性的属性值按列在第一数据表中存储;以及
所述第二类别数据存储在所述第二存储单元的第二数据表中,所述第二类别数据的子类别按行在第二数据表中存储,所述第二类别数据的子类别的各自定义属性的属性值按列在第二数据表中存储。
7.根据权利要求6所述的系统,其中,
所述第一数据表与所述第二数据表采用Vertica数据表。
8.根据权利要求6所述的系统,其中,
所述存储位置选择模块包括:
可用列计算模块,其适于基于如下公式计算所述存储单元选择模块选定的数据表中能够用于存储所述自定义属性的所有可用列CA:
CA=所有列CT-(所有被使用过的列CU-优先列CP)-当前子类别的所有自定义属性使用过的列CTU
其中,所述优先列CP为与要存储的自定义属性的属性名和属性值的数据类型相同的列;
判断模块,其适于判断所述可用列计算模块计算得到的可用列是否能够用于存储所述自定义属性的属性值;
列添加模块,其适于在所述判断模块判断所述可用列不能用于存储所述自定义属性的属性值的情形下,在所述数据表中增加预定数量的列,并将其加入到计算得到的所有可用列中;和
列选择模块,其适于从所有可用列中选定列用于存储当前子类别的所述自定义属性的属性值。
9.根据权利要求8所述的系统,其中,
所述列选择模块将从计算得到的所有可用列与所述优先列的交集中的第一列开始的预定数量的列选定为用于存储所述自定义属性,或者将从所有可用列去除所述优先列的剩余列中的第一列开始的预定数量的列选定为用于存储所述自定义属性。
10.根据权利要求2-9中任何一项所述的系统,其中,
所述子类别还包括预先设置的预置属性,所述预置属性的元数据信息已经事先记录在所述元数据记录装置中,所述元数据信息包括将所述预置属性具有的属性值存储在数据存储模块中的指定存储位置;
所述数据解析装置解析所述需要存储的数据的预置属性;
所述数据存储装置根据所述元数据记录装置中记载的所述预置属性的元数据信息,将所述预置属性存储在指定存储位置。
11.根据权利要求2-9中任何一项所述的系统,其中,
所述元数据记录装置包括多个元数据表,所述元数据表包括:
第一元数据表,其适于记录子类别名称与子类别标识符;以及
第二元数据表,其适于记录所述子类别包括的属性的属性名、属性类型、和在存储装置中的存储位置。
12.根据权利要求2-9中任何一项所述的系统,其用于存储数据分析中的数据,
所述第一类别为事件类别,所述第二类别为用户类别,所述第一类别的子类别是所述事件类别包含的一个或多个具体事件,所述第二类别的子类别是所述用户类别包含的一个或多个具体用户。
13.数据存储方法,适用于对不断采集的大量数据进行存储,且所述不断采集的数据存在着变化,其特征在于,所述采集的数据根据用户需求而设置有多个数据种类,且所述数据种类是根据用户需求的变化而可变化的,所述数据种类基于数据的特征而划分成多个数据种类,所述数据的特征包括数据类别、子类别、子类别的属性,其中所述类别包括一个或多个子类别,每个子类别分别具有一种或多种属性;所述数据存储方法包括:
获取需要存储的数据,所述需要存储的数据为从客户端或服务器侧不断采集的数据在经过转换和处理后而需要进行存储的数据;
对所述需要存储的数据进行解析,获得所述需要存储的数据的特征并根据所述需要存储的数据的特征确定所述需要存储的数据的存储位置;
记录所述需要存储的数据的元数据信息,所述元数据信息包括所述需要存储的数据的特征及存储位置;以及
基于所记录的元数据信息,将所述解析出的数据存储在相应的存储位置。
14.根据权利要求13的方法,其中,
所述需要存储的数据包括第一类别数据和第二类别数据,每个子类别分别具有一种或多种自定义属性,每种自定义属性具有属性名及属性值;
所述第一类别数据存储在第一数据表中,所述第二类别数据存储在第二数据表中;
所述对所述需要存储的数据进行解析而获得需要存储的数据的特征并确定其存储位置的步骤包括解析所述需要存储的数据的类别、子类别、所述子类别包含的自定义属性、以及所述自定义属性的属性值的数据类型,确定所述自定义属性的属性值在对应数据表中的列;
所述基于所记录的元数据信息将所述解析出的数据存储在相应的存储位置的步骤包括将所述自定义属性的属性值存储在所述对应数据表中的列,且该列用于存储具有相同属性名和属性值的数据类型相同的自定义属性,该列所存储的属性值的数据类型由该列第一次存储的属性值的数据类型确定。
15.根据权利要求14所述的方法,其中,
所述属性值的数据类型包括:数字类型、字符串类型、日期类型、日期时间类型、布尔类型、以及由字符串集合而形成的复合类型。
16.根据权利要求14所述的方法,其中,
解析所述需要存储的数据的类别、子类别、所述子类别包含的自定义属性、以及自定义属性的属性值的数据类型并确定各自定义属性的属性值在对应数据表中存储的列的步骤包括:
解析所述需要存储的数据中包含的新的子类别和已有子类别、所述子类别中的新的自定义属性和已有的自定义属性;
对所述新的子类别进行注册,为其分配子类别标识号,所述子类别识别号确定所述自定义属性在对应数据表存储的行;
对所述新的子类别和所述已有子类别二者所包含的新的自定义属性进行注册,建立元数据信息,确定所述新的自定义属性的属性值在对应数据表中存储的列;
对于所述已有子类别中的已有自定义属性,解析其属性值的数据类型,判断所述属性值的数据类型与元数据信息中记录的数据类型是否一致,如果一致则按照所记录的元数据信息存储在对应存储位置,如果不一致,则视为异常。
17.根据权利要求16所述的方法,其中
对所述新的子类别和所述已有子类别二者所包含的新的自定义属性进行注册并确定所述新的自定义属性的属性值在对应数据表中存储的列的步骤包括:
根据所述新的自定义属性所属的数据类别确定要存储的对应数据表;
获取所述对应数据表的列使用状态;以及
根据所述对应数据表的列使用状态和所述自定义属性的属性值的数据类型,确定各自定义属性在所述对应数据表中存储的列。
18.根据权利要求17所述的方法,其中,
所述根据所述对应数据表的列使用状态和所述自定义属性的属性值的数据类型确定各自定义属性在所述对应数据表中存储的列的步骤包括:
基于如下公式计算所述对应数据表的可用列CA:
CA=所有列CT-(所有被使用过的列CU-优先列CP)-所述子类别的所有自定义属性使用过的列CTU
其中,所述优先列CP为与要存储的自定义属性的属性名和属性值的数据类型相同的列;
判断所述计算得到的可用列是否能够用于存储所述自定义属性的属性值;
在判断所述可用列中不能用于存储所述自定义属性的属性值的列的情形下,在所述对应数据表中增加预定数量的列;以及
从所有可用列中选定列用于存储所述自定义属性的属性值。
19.根据权利要求18所述的方法,其中,
所述从所有可用列中选定列用于存储所述自定义属性的属性值的步骤包括:
将从所有可用列与所述优先列的交集中的第一列开始的预定数量的列选定为用于存储所述自定义属性;或者
将从所有可用列去除所述优先列的剩余列中的第一列开始的预定数量的列选定为用于存储所述自定义属性。
20.根据权利要求14-19中任何一项所述的方法,其中,
所述子类别还包括预先设置的预置属性,并且事先记录了所述预置属性的元数据信息,所述预置属性的元数据信息包括将所述预置属性具有的属性值存储的指定存储位置以及属性值的数据类型;
所述对所述需要存储的数据进行解析的步骤还包括解析所述子类别的预置属性、以及所述预置属性的属性值的数据类型,确定所述预置属性的属性值的存储位置;
所述基于所记录的元数据信息将所述解析出的数据存储在相应的存储位置的步骤还包括将所述预置属性存储在指定存储位置。
21.根据权利要求14-19中任何一项所述的方法,其中,
所述记录所述需要存储的数据的元数据信息的步骤包括:
将第一类别的数据的元数据信息记录在第一元数据表中,以及
将第二类别的数据的元数据信息记录在第二元数据表中。
22.根据权利要求14-19中任何一项所述的方法,其中,
所述第一类别为事件类别,所述第二类别为用户类别,所述第一类别的子类别是所述事件类别包含的一个或多个具体事件,所述第二类别的子类别是用户类别包含的一个或多个具体用户。
23.数据查询装置,适于对根据权利要求1-12中任何一个所述的数据存储系统存储的数据进行查询,其特征在于,包括:
第一接收模块,其适于接收来自WEB前端的查询请求,所述查询请求包含一个或多个查询条件和一个或多个显示参数;
第二解析模块,其适于基于所述数据存储系统的元数据记录装置中记录的元数据信息解析所述查询请求,获得解析结果;
查询机制建立模块,其适于基于所述第二解析模块的解析结果建立查询机制;
第一查询模块,其适于根据所建立的查询机制查询所述数据存储系统中的数据存储装置中的数据,获得查询结果;
第一存储模块,其适于存储所述查询结果,以及
第一发送模块,其适于将所述查询结果发送给所述WEB前端。
24.根据权利要求23所述的数据查询装置,其中,
所述第二解析模块基于对所述查询请求的解析,构建SQL语句片段;
所述查询机制建立模块基于所述第二解析模块构建的SQL语句片段构建完整的查询SQL语句;
所述第一查询模块基于所述查询机制建立模块所构建的完整的查询SQL语句对所述数据存储装置中存储的数据进行查询并获得查询结果。
25.根据权利要求23所述的数据查询装置,其中,
所述第一发送模块将所述查询结果以所述WEB前端能够展现的格式进行重构,然后发送给所述WEB前端。
26.数据查询方法,适于对根据权利要求13-22中任何一项所述的数据存储方法存储的数据进行查询,其特征在于,包括:
获取来自WEB前端的查询请求,所述查询请求包含一个或多个查询条件和一个或多个显示参数;
基于被存储的数据的元数据信息,解析所述查询请求中包含的查询条件和显示参数,获得解析结果;
基于所述解析结果构建查询机制;
基于所构建的查询机制查询所述存储的数据,获取查询结果;以及
将所述查询结果发送至所述WEB前端。
27.根据权利要求26所述的数据查询方法,其中,
所述获得解析结果的步骤包括获得构建SQL语句的片段;
所述基于所述解析结果构建查询机制的步骤包括基于所述构建的SQL语句片段构建完整的查询SQL语句;
所述基于所构建的查询机制查询所述存储的数据的步骤包括基于所构建的完整的查询SQL语句对所述存储的数据进行查询。
28.根据权利要求26所述的数据查询方法,其中,
所述将所述查询结果发送至所述WEB前端的步骤包括将所述查询结果以所述WEB前端能够展现的格式进行重构之后发送给所述WEB前端。
29.数据展现系统,其特征在于,包括:
显示装置,其位于WEB前端,适于接收使用者对查询条件和显示参数的输入、以及显示基于所述查询条件和显示参数所获得的查询结果;
第二接收模块,其位于WEB服务器中,适于接收所述查询条件和显示参数,并传送至根据权利要求23-25中任何一项所述的数据查询装置;
根据权利要求23-25中任何一项所述的数据查询装置,适于根据所述查询条件和显示参数,查询根据权利要求1-12中任何一项所述的数据存储系统中的数据存储装置存储的数据,获得查询结果;以及
获取模块,其位于WEB服务器中,适于从所述数据查询装置中获取所述查询结果,并将所述查询结果发送至所述显示装置。
30.根据权利要求29所述的数据展现系统,还包括:
轮询模块,其位于WEB服务器中,适于以预定时间间隔查询并获取所述数据存储系统中的元数据记录装置记录的元数据信息,所述元数据信息中包含多个字段,所述字段为所述查询条件中的一个参数;和
第二存储模块,其适于存储所述轮询模块获取的元数据信息;
所述第二接收模块接收来自所述显示装置的使用者对查询条件的选择的触发;
所述获取模块基于来自所述显示装置的对查询条件的选择的触发,从所述第二存储模块中获取所有字段,发送给所述显示装置进行显示。
31.数据展现方法,其特征在于,包括:
接收使用者输入的查询条件和显示参数;
根据所述查询条件和显示参数,采用权利要求26-28中任何一项所述的数据查询方法,查询根据权利要求13-22中任何一项所述的数据存储方法存储的数据,获得查询结果;以及
将所述查询结果发送至WEB前端进行展现。
32.根据权利要求31所述的数据展现方法,还包括:
以预定时间间隔查询并获取所述存储的数据的元数据信息,所述元数据信息中包含多个字段,所述字段为所述查询条件中的一个参数;
将获取的所述元数据信息存储在WEB服务器的内存储器中;
基于来自所述WEB前端的对查询条件的选择的触发,从WEB服务器的内存储器获取所述元数据信息中包含的所有字段;以及
将获取的所有字段发送至所述WEB前端并显示在相应的选择框下。
33.数据分析系统,其特征在于,包括:
数据采集系统,其适于从客户端和/或服务器中采集数据,所述采集的数据包含根据用户需求而设置的多个数据种类;
数据传输系统,其适于将所述数据采集系统所采集的数据进行提取、转换并传输;
根据权利要求1-12中任何一项所述的数据存储系统,其适于将所述数据传输系统传输的数据进行存储、并记录相应的元数据信息;以及
根据权利要求29或30所述的数据展现系统,其适于基于使用者输入的查询条件和显示参数,查询所述数据存储系统存储的数据并获取查询结果,然后显示在WEB前端。
34.数据分析方法,其特征在于,包括:
从客户端和/或服务器中采集数据,所述采集的数据包含根据用户需求而设置的多个数据种类;
将所述采集的数据进行提取、转换并传输;
将所述传输的数据根据权利要求13-22中任何一项所述的数据存储方法进行存储、并记录相应的元数据信息;以及
根据权利要求31或32所述的数据展现方法,基于使用者输入的查询条件和显示参数,从所述存储的数据中获得查询结果并在WEB前端显示。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201610024279.6A CN105718515B (zh) | 2016-01-14 | 2016-01-14 | 数据存储系统及其方法和数据分析系统及其方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201610024279.6A CN105718515B (zh) | 2016-01-14 | 2016-01-14 | 数据存储系统及其方法和数据分析系统及其方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN105718515A CN105718515A (zh) | 2016-06-29 |
CN105718515B true CN105718515B (zh) | 2019-09-10 |
Family
ID=56147087
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201610024279.6A Active CN105718515B (zh) | 2016-01-14 | 2016-01-14 | 数据存储系统及其方法和数据分析系统及其方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN105718515B (zh) |
Families Citing this family (28)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN107666499B (zh) * | 2016-07-28 | 2021-01-26 | 北京京东尚科信息技术有限公司 | 用于服务器的信息存储方法和装置 |
CN106570129A (zh) * | 2016-10-27 | 2017-04-19 | 南京邮电大学 | 一种对实时数据进行快速分析的存储系统及其存储方法 |
CN108153744A (zh) * | 2016-12-02 | 2018-06-12 | 上海中兴软件有限责任公司 | 一种数据存储维护方法及装置 |
CN108153662A (zh) * | 2016-12-05 | 2018-06-12 | 北京国双科技有限公司 | 一种数据测试方法及数据测试系统 |
CN106933971B (zh) * | 2017-02-13 | 2020-06-16 | 北京优炫软件股份有限公司 | 一种基于科技服务的数据分析统计系统 |
CN107133329B (zh) * | 2017-05-09 | 2022-03-08 | 腾讯科技(深圳)有限公司 | 数据处理方法、数据处理装置及存储介质 |
CN107729406B (zh) * | 2017-09-25 | 2020-06-02 | 深圳达实智能股份有限公司 | 一种数据分类存储方法及装置 |
CN110069486B (zh) * | 2017-09-27 | 2021-08-13 | 北京国双科技有限公司 | 一种存储自定义参数的方法及装置 |
CN110020357B (zh) * | 2017-10-31 | 2021-08-24 | 北京国双科技有限公司 | 数据存储方法、装置、存储介质和处理器 |
CN107977226A (zh) * | 2017-11-22 | 2018-05-01 | 北京酷我科技有限公司 | 一种iOS数据正向自动解析策略 |
CN108344963B (zh) * | 2018-01-05 | 2021-03-02 | 和芯星通(上海)科技有限公司 | 确定磁传感器数据的方法及装置、电子设备及存储介质 |
CN108932188A (zh) * | 2018-05-03 | 2018-12-04 | 北京奇虎科技有限公司 | 一种数据处理方法和装置 |
CN108710677B (zh) * | 2018-05-18 | 2021-08-17 | 中国兵器工业新技术推广研究所 | 通过NoSQL数据库实现BOM数据多组织多视图的解决方法 |
CN109213444A (zh) * | 2018-08-17 | 2019-01-15 | 上海小蚁科技有限公司 | 文件存储方法及装置、存储介质、终端 |
CN110875885B (zh) * | 2018-08-31 | 2022-04-12 | 武汉斗鱼网络科技有限公司 | 消息处理方法、服务器、终端、系统及存储介质 |
CN109542893B (zh) * | 2018-10-19 | 2021-05-28 | 深圳点猫科技有限公司 | 一种基于编程语言的复合数据结构设置方法及电子设备 |
CN111274586B (zh) * | 2018-12-04 | 2024-04-05 | 北京京东尚科信息技术有限公司 | 保存数据的方法和装置 |
CN109656955A (zh) * | 2018-12-10 | 2019-04-19 | 泰康保险集团股份有限公司 | 用户数据查询方法、系统与存储介质 |
CN109669995A (zh) * | 2018-12-25 | 2019-04-23 | 北京锐安科技有限公司 | 数据存储、质量计算方法、装置、存储介质及服务器 |
CN110399374A (zh) * | 2019-07-05 | 2019-11-01 | 东软集团股份有限公司 | 数据检索方法、装置、存储介质及电子设备 |
CN110705891A (zh) * | 2019-10-11 | 2020-01-17 | 集奥聚合(北京)人工智能科技有限公司 | 一种基于高可配可变更的数据处理方法 |
CN111078639B (zh) * | 2019-12-03 | 2022-03-22 | 望海康信(北京)科技股份公司 | 数据标准化方法、装置以及电子设备 |
CN111565191A (zh) * | 2020-05-07 | 2020-08-21 | 南通保利佳服务外包有限公司 | 一种数据压缩、传输系统及方法 |
CN111752954B (zh) * | 2020-06-29 | 2022-08-12 | 深圳前海微众银行股份有限公司 | 一种大规模特征数据存储的方法及装置 |
CN112783895B (zh) * | 2021-01-11 | 2023-11-10 | 中国科学院软件研究所 | 面向软件定义卫星的数据库访问处理方法、装置及设备 |
CN113590616A (zh) * | 2021-07-16 | 2021-11-02 | 深信服科技股份有限公司 | 一种元数据的处理方法、装置、电子设备及存储介质 |
CN114748875B (zh) * | 2022-05-20 | 2023-03-24 | 一点灵犀信息技术(广州)有限公司 | 数据存盘方法、装置、设备、存储介质及程序产品 |
CN117412061A (zh) * | 2022-07-08 | 2024-01-16 | 清华大学 | 数据存储方法、读取方法、装置、存储介质及程序产品 |
Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104298574A (zh) * | 2014-09-16 | 2015-01-21 | 南京斯坦德云科技股份有限公司 | 一种数据高速存储处理系统 |
CN104462362A (zh) * | 2014-12-08 | 2015-03-25 | 曙光信息产业(北京)有限公司 | 一种数据存储、查询、加载方法及装置 |
Family Cites Families (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US8700561B2 (en) * | 2011-12-27 | 2014-04-15 | Mcafee, Inc. | System and method for providing data protection workflows in a network environment |
-
2016
- 2016-01-14 CN CN201610024279.6A patent/CN105718515B/zh active Active
Patent Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104298574A (zh) * | 2014-09-16 | 2015-01-21 | 南京斯坦德云科技股份有限公司 | 一种数据高速存储处理系统 |
CN104462362A (zh) * | 2014-12-08 | 2015-03-25 | 曙光信息产业(北京)有限公司 | 一种数据存储、查询、加载方法及装置 |
Also Published As
Publication number | Publication date |
---|---|
CN105718515A (zh) | 2016-06-29 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN105718515B (zh) | 数据存储系统及其方法和数据分析系统及其方法 | |
US11792291B1 (en) | Proxying hypertext transfer protocol (HTTP) requests for microservices | |
US11645286B2 (en) | Dynamic data processor for streaming and batch queries | |
US20230169084A1 (en) | Interactive visualization of a relationship of isolated execution environments | |
US10997192B2 (en) | Data source correlation user interface | |
US11704490B2 (en) | Log sourcetype inference model training for a data intake and query system | |
US20220291984A1 (en) | Monitoring statuses of monitoring modules of a distributed computing system | |
US11226964B1 (en) | Automated generation of metrics from log data | |
JP5620933B2 (ja) | エンタープライズウェブマイニングシステム及び方法 | |
US10762049B1 (en) | Extracting machine data generated by an isolated execution environment from a chunk of data generated by an isolated execution environment manager | |
US20220036177A1 (en) | Data field extraction by a data intake and query system | |
CN100401292C (zh) | 用于使用倾向分析进行搜索查询处理的系统和方法 | |
CN102667761B (zh) | 可扩展的集群数据库 | |
CN110019396A (zh) | 一种基于分布式多维分析的数据分析系统及方法 | |
CN104065565B (zh) | 推送消息的方法、服务器、客户端装置和系统 | |
CN108885627A (zh) | 向远程客户端提供查询结果数据的查询即服务系统 | |
US9946752B2 (en) | Low-latency query processor | |
EP2583190A1 (en) | Determining and using search term weightings | |
CN102117320A (zh) | 一种结构化数据搜索的方法和装置 | |
US11106713B2 (en) | Sampling data using inverted indexes in response to grouping selection | |
US11663172B2 (en) | Cascading payload replication | |
CN106570013A (zh) | 页面访问数据的处理方法和装置 | |
CN107480268A (zh) | 数据查询方法及装置 | |
CN111414410A (zh) | 数据处理方法、装置、设备和存储介质 | |
WO2022026984A1 (en) | Data field extraction model training for a data intake and query system |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |