各式结构化数据的动态接入存储查询,这一需求相信有很多人都遇到过,随着实现技术路线选择的不同,遇到的问题出入大了,其解决办法也是大相径庭。数据存储在哪儿,是关系型数据库,还是NoSQL数据库,是MySQL还是Oracle,怎么建立索引,建立什么类型的索引,都是大学问。下面,我要把我对这一解决办法的思考总结一下,有成熟的也有不成熟的,希望大家一起共同探讨。
关键词:结构化数据, 动态, 接入, 存储, 查询

 
首先,我们得定义一下在本文中什么是结构化数据,这里的结构化数据主要是指扁平化的、可以由基础数据类型组合成的数据,例如:{"data":{"name":"wang anqi","age":28,"money":1653.35,"XX_date":"2013-12-3"}},它们是可以很容易被存入关系型数据库的,我们要讨论的就是这种数据。对应的,非结构化数据这里是指那些需要存储在文件系统中的,不是扁平化的数据。
 
那么,什么又是“各式结构化数据”呢,在本文中?这是一个数据集合,有可能集合中的每一条数据结构都是不尽相同的,例如:{"data":{"name":"wang anqi","age":28,"money":1653.35,"XX_date":"2013-12-3"}},和{"angel":{"address":"清凉山公园","user":289770363}}同时存在于一个数据集合中,它们结构不同,简单地说:第一条数据有四个属性,第二条数据只有两个属性,属性名称和类型都不一样。“各式”包括了不定数量的属性,不定的属性名称、不定的数据类型。
 
解释清楚名词了,再解释一下动词:“动态接入”。在普遍情境下,你只会遇到将固定数据结构的数据存储入库,这里的入库主要还是指MySQL一类的关系型数据库。那么你可以选择使用Hibernate等ORM工具或不使用,来进行数据的存储读取,在使用ORM工具的情况下,要首先定义好数据的数据结构,写死在xml里或是java代码里。
 
一般情况下,你是不会遇到这样的需求的:对于不能事先确定数据结构的数据,我要把它们存储到关系型数据库中,并提供“合法性检验”、“更新”、“查询”等基本数据操作。要说的是,如果要把它们存储到HBase这种NoSQL数据库中,那是再好不过的了,配合着HBase与Solr的集成(详见之前的博客:大数据架构-使用HBase和Solr将存储与索引放在不同的机器上),搜索也不是件难事,唯一可能出现的难点在于:Solr对于Schema中filedName的配置,因为结构是动态的,所以fildName也是动态的,这其实也是很好处理的,有位微软的同学已经跟我咨询过这个问题了;事实上,这样的例子是很常见的。
 
但是往往,事与愿违,很有可能存在着其它的约束条件制约着你:必须使用关系型数据库,那么一整套解决办法是需要设计的。因为当你使用Hibernate时,你不能再把一个数据结构写死在代码里,因为它不是固定的,你该如何入库,该如何查询数据,这都是问题。
 
要处理好“各式结构化数据动态接入管理”,应该分成以下几步:一、定义数据;二、动态管理;三、数据接入;四、数据查询。
一、定义数据

 
假如相关业务单位提供的有这么一类数据,这里用一条数据举例来说明:产品A 产品序列号为:A8815001 生产日期为:2013/12/09 13:33:33 供应商为:阿里巴巴 产品质量为:509g 是否合格为:是。我们可以从中大致看出各字段的数据类型,通过面向对象的方法定义出这么一个产品A类也很容易。现在我们要把这条数据存储到关系型数据库中,还是需要一引起先前处理的。 
 
定义数据是基础,无论你的数据结构再怎么不固定,它也应该有个名字,它的属性也应该是由基础数据类型构成的。基础数据类型就像是构成世界万物的基本元素Ka、Ca、H、O等(请原谅我的灵感来自于《绝命毒师》),它们肯定是要事先定义好的,我们数据库中能够接入的数据必须由这些组成,如: String、Integer、Long、BigDecimal、Boolean、Calendar、Date、Time、Blob等,Time是以什么样的格式存在的,18:09:32还是18:9:32.3?Date是以什么样的格式存在的,2000-10-8 18:09:32还是2000/10/8 18:9:32.3?
 
因此基础数据类型,需要作为一项很重要的业务约定,同各个“干系人”共享。就是说,在这里,我定义的基础数据类型,并不是我一个人说的算了的,而是要同相关业务单位开会沟通,这些基础数据类型是否可以囊括它们提供的数据结构的所有内容。毕竟,要接入的数据类型是由他们提供的,他们事先也需要把各种数据类型定义好,比如上面的产品A的结构,都要以文档《产品A数据结构定义》的形式记录下来。在这一步需要产生一个文档,《基础数据定义文档》。
 
光是有基础数据类型的概念还远远不够,可能在产品A的数据结构文档中,还定义了某一属性值是否可为空,它的取值范围是多少,以及其它业务相关的配置等等,那么就需要有一张数据定义表,来记录对数据的要求。举个例子,我们要接入管理的数据有:产品A,根据文档《产品A数据结构定义》和《基础数据定义文档》和《业务需求文档》,它的数据结构可以在数据库中被定义成这样:
 
类型名称(DATA_TYPE) 属性中文名称(ATTR_CNAME) 属性名称(ATTR_NAME) 属性类型(ATTR_TYPE) 是否可空(IS_NULLABLE) 属性长度(ATTR_LENGTH) 是否可查(IS_SEARCHABLE) 属性约束(ATTR_RES) ......
产品A 产品序列号 PRO_SEQ String F 32 T ^[\s\S]{0,32}$  
产品A 生产日期 PRO_DATE Date F 19 T ^\d{4}-\d{2}-\d{2}( )+\d{2}(:\d{2}){2}$  
产品A 供应商 SUPPLY String T 60 T ^[\s\S]{0,60}$  
产品A 产品质量 WEIGHT Integer F 5 T ^\d{1,5}(\.\d*)?$  
产品A 是否合格 IS_QUALIFIED Boolean T 1 F ^\d{1,1}(\.\d*)?$  
......                

 
说明一下,这是的“是否可查”表示的是是否可以针对此属性作为查询条件,进行数据搜索,这是业务相关的;这里的“属性约束”一列,它采用“正则表达式”的方式,在验证数据正确性时,将起到很大的作用。验证数据正确性这部分逻辑,放在数据接入中做。
这样一来,我们就能把对“产品A”这种数据类型的具体的数据要求放在数据库中存储起来,我们估且把这些数据要求集合而成的表命名为:属性表(TBL_ATTRIBUTE),当然这是可以通过使用Hibernate的方式来进行增删改的操作的。别忘了,一个数据类型的增删改,还需要改一张表:数据类型管理表(TBL_DATATYPE),它存储了所有的被动态接入管理的数据类型,其表结构及其可能存储的数据内容如下所示:
 
类型名称(DATA_TYPE) 表名(TABLE) 创建时间(CREATE_TIME) 修改时间(MODIFY_TIME) ......
产品A TBL_PRO_A 2014/10/8 8:43:23 2014/10/8 15:2:12  
产品B TBL_PRO_B 2014/10/8 10:16:56 2014/10/8 16:37:7  
......        
二、动态管理

定义完了要接入的数据类型,我们需要的是有这么一个函数来完成:addDataType(DataType dt, List<Attribute> attrList)的功能,只要我们定义好了DataType数据类型、List<Attribute>属性列表,那么我们就要能够动态地把这种数据类型加入“王安琪豪华数据”中进行管理。数据类型的管理容易,通过数据类型管理表(TBL_DATATYPE)和属性表(TBL_ATTRIBUTE),将传入的 DataType dt 和 List<Attribute> attrList 入库即可,主要的难点还是在于动态的把此种数据类型的存储表建立起来,因为每定义一种数据类型就要创建一张表。在这一步,我们需要产生或更新三张表:数据类型管理表(TBL_DATATYPE)、属性表(TBL_ATTRIBUTE)和产品A表(TBL_PRO_A)。
对于举例的“产品A”,它生成的存储表中的内容应该是这样的:
 
PRO_SEQ PRO_DATE SUPPLY WEIGHT IS_QUALIFIED
A0001234567 2011-06-09 12:29:19 杭州诺基亚西门子科技有限公司 398 1
Angel89Wang 2013-04-05 08:10:23 江苏金陵科技有限公司 125  
......        
 
在填入这些数据之前,我们应该把这张表建立起来,建立的依据就是数据类型管理表(TBL_DATATYPE)和属性表(TBL_ATTRIBUTE)中对“产品A”的定义,要创建的表名为:TBL_PRO_A,各个列名为:PRO_SEQ(32位字符串型)、PRO_DATE(时间型)、SUPPLY(60位字符串型)、WEIGHT(5位整数型示)、IS_QUALIFIED(布尔型)。
 
在这里,我使用的是Hibernate所支持的tableName.hbm.xml来动态生成表的,当然在此之前,需要先把tableName.hbm.xml文件按照定义的格式生成好。然后再调用SchemaUpdate schemaUpdate = new SchemaUpdate(config);

schemaUpdate.execute(truetrue);来生成表。

 
其实动态管理这一步,就不只是动态建表这么简单,上面说的比较狭隘,从广义上理解,它应该被分解为下面几个操作:1、动态创建;2、动态修改;3、动态删除。
 
动态创建就是通过addDataType(DataType dt, List<Attribute> attrList)来实现的,那么我们还需要:removeDataType(String dataTypeName)来实现动态删除,updateDataType(DataType dt, List<Attribute> attrList)来实现动态修改。
 
动态创建就是刚刚说的那一部分,通过在数据类型管理表(TBL_DATATYPE)、属性表(TBL_ATTRIBUTE)中添加一个数据类型,并动态生成一张存储表。动态修改就比较麻烦了,数据类型管理表(TBL_DATATYPE)、属性表(TBL_ATTRIBUTE)中内容容易修改,可是如果数据存储表中存有数据,应该怎么处理。我采用了和一般数据库通用的处理方式,若表中有数据,则不给动态修改,必须通过删除再创建的方式来达到效果。动态删除,我采用的处理方式是,先删除此种数据类型定义,也即在数据类型管理表(TBL_DATATYPE)和属性表(TBL_ATTRIBUTE)把相应数据删除,然后再删除实际存储表中的数据。当然,具体的处理方法,还是要跟相关业务单位协商,了解他们的需求,如果他们就是不要删除数据存储表中的数据呢。
 
动态建表是这里比较容易出问题的地方,因为如果我们新建一种数据类型:“typeA”,然后再把这个数据类型删除,此时就要处理好它在Hibernate上下文中的位置,也要从Hibernate上下文中删除,据我所知,Hibernate对这个还没有支持,也可能是我才疏学浅,欢迎各位提供解决办法。
 
存在问题
1、数据字典问题
数据字典是数据管理系统中经常使用的,这主要是用来保证灵活性的,它基本是由key-value键值对来实现的,在实际数据存储中存储key,但在显示时取出value用来显示。它的好处为:更改value不改key,可以做到显示灵活配置,比如TB在系统中原先显示为“淘宝”,后来想要它显示为“TaoBao”,那么只要在数据字典项中更改value值即可。
那么问题就来了,假如数据类型A中某属性应用了某数据字典,key-value1,它要存储的是key,那么我们就还要对这一数据字典进行管理。在我们的系统中也要存在这份数据字典,并且指明此属性对应的数据字典是哪张表,哪一列为key,哪一列为value。这当然是可以实现的,稍微麻烦一些。
再假如数据类型A中某属性应用了某数据字典,key-value1,数据类型B中某属性应用了key-value2,它们的数据字典还可能相同的地方,比如value值都是相同的,为了节约存储空间,我们把这两个数据字典整合进一张表中key1-key2-value,处理方法如上,实现可以,但麻烦。数据字典问题不止是存在于定义数据和动态管理这两个步骤中,下面的数据接入、数据查询遇到的问题将更加棘手。
处理办法:
a、唯一化key。
b、你的建议。
 
2、动态建表问题
上面说了,在删除数据类型时,要在Hibernate上下文中处理好它,但是没有找到好的解决办法。欢迎不吝赐教。
处理办法:
a、悬而未决,你的建议。
 
上面讲了一、定义数据,二、动态管理,还有:三、数据接入,四、数据查询 两个步骤,将在以后的文章中详细说明。
来自王安琪http://www.cnblogs.com/wgp13x/
作者:Angel 
出处:http://www.cnblogs.com/wgp13x/ 
欢迎转载或分享,但请务必声明文章出处。
如果文章对您有帮助,希望你能推荐关注

王安琪,英文名Angel,南京邮电大学计算机应用技术硕士学位。 熟悉Java、C#编程语言。专注于WebService、海量数据处理、搜索引擎技术、消息中间件技术、分布式文件存储、.NET应用程序开发、系统架构设计。主要从事数据管理系统的研发,就职于江苏金陵科技集团有限公司。

Email:aitanjupt@hotmail.com

QQ:289770363

各式结构化数据 动态-接入-存储-查询 的处理办法 (第一部分)相关推荐

  1. 各式结构化数据 动态 接入-存储-查询 的处理办法 (第二部分)

    各式结构化数据的动态接入存储查询,这一需求相信有很多人都遇到过,随着实现技术路线选择的不同,遇到的问题出入大了,其解决办法也是大相径庭.数据存储在哪儿,是关系型数据库,还是NoSQL数据库,是MySQ ...

  2. 各式结构化数据 动态 接入-存储-查询 的处理办法 (第一部分)

    各式结构化数据的动态接入存储查询,这一需求相信有很多人都遇到过,随着实现技术路线选择的不同,遇到的问题出入大了,其解决办法也是大相径庭.数据存储在哪儿,是关系型数据库,还是NoSQL数据库,是MySQ ...

  3. 海量结构化数据解决方案-表格存储场景解读

    简介: 数据是驱动业务创新的最核心的资产.不同类型的数据如非结构化数据(视频.图片等).结构化数据(订单.轨迹),面向不同业务的使用要求需要选择适合的存储引擎,能够真正发挥数据的价值.针对于海量的非强 ...

  4. 结构化数据和非结构化数据的分析

    结构化数据和非结构化数据的分析 一. 什么是数据 二. 数据的分类 1. 按性质分为 2. 按表现形式分为 3. 按表现形式分为 三. 结构化数据和非结构化数据 1. 什么是结构化数据 2. 什么是非 ...

  5. 非结构化数据定义、处理方法及重要性

    一.非结构化数据定义 不方便用数据库二维逻辑表来表现的数据即称为非结构化数据,包括所有格式的办公文档. 文本.图片. 标准通用标记语言下的子集 XML. HTML.各类报表.图像和音频/视频信息等等. ...

  6. 技术20期:结构化数据与非结构化数据:有什么区别?

    查看结构化和非结构化数据.它们的主要区别以及哪种形式最能满足您的业务需求. 并非所有数据都是平等的.有些数据是结构化的,但大部分是非结构化的.结构化和非结构化数据以不同的方式获取.收集和扩展,并且每一 ...

  7. 分析非结构化数据和非结构化处理

    文章目录 一.非结构化数据的定义 二.非结构化处理的重要性 三.数据类型 四.非结构化处理的方法和手段 1. 采集 2. 查询 3. 存储 4. 前景 一.非结构化数据的定义 非结构化数据是数据结构不 ...

  8. 浅述非结构化数据与非结构化处理

    文章目录 一.非结构化数据的定义 二.非结构化处理的重要性 1. 有大量的非结构化数据需要处理 2. 非结构化数据蕴藏着大量的价值 3. 非结构化处理不需要依靠数据科学家团队 4. 终端用户授权 三. ...

  9. 结构化数据、非结构化数据、半结构化数据

    结构化数据.非结构化数据以及半结构化数据是对存储形式的一种数据类型分析,有助于企业细分行业案例,帮助存储合作伙伴更好地解决应用实施方案. 定义 结构化数据,即行数据,存储在数据库里,可以用二维表结构来 ...

最新文章

  1. ajax给data赋值,vue 2.0 methods 里ajax生成的数据,怎么赋值给data
  2. Mac上Homebrew的使用 (Homebrew 使 OS X 更完整)
  3. Java中this与super的区别
  4. nginx设置http强制跳转https
  5. Mysql orangepi_SSH远程登录香橙派Orange Pi Zero2开发板的操作方法
  6. 双十一最具性价比机型,Redmi K30S至尊纪念版上手体验
  7. Python基础之完数输出
  8. 百度地图python_python百度地图API爬取街景
  9. TIM-VX编译体验
  10. 抖抖.....抖个不停的伺服电机——转动惯量匹配技术及资料分享
  11. Adams 线性多步积分器(一)
  12. 瞬变抑制二极管TVS原理简介
  13. TIdTCPClient
  14. 手脱ASPack v2.12
  15. Flink Transformation
  16. Java 用“等待-通知”机制优化循环等待
  17. 该网页无法访问未连接上服务器是什么意思,浏览器打不开该网页,因为无法连接到服务器...
  18. 2011-12-21的告别信
  19. 拆散彩虹:牛顿生命最后时光里的棱镜
  20. 项目管理专业英语-项目预测

热门文章

  1. 关闭Anti Aliasing 的情况下单独对3D模型抗锯齿
  2. 牛逼!知道这100 个网络基础知识,成了半个网络高手!(文末附PDF版本)
  3. quart 定时器介绍详解
  4. chembiodraw入门系列-1
  5. 儿童护眼灯哪个品牌最好?盘点儿童护眼台灯品牌
  6. (嵌入式)ARM开发环境入门-----一个简单的LED灯闪烁的实现
  7. 无名2021/01/13
  8. Android-application
  9. 记录linux 生成crash dump文件步骤
  10. Multisim基础 网络名称 整理混乱的电路图