数据结构动态查找表的查找以什么存储结构为主

百度新闻搜索——全球最大的中文新闻平台
加载中请您耐心等待...
加载中,请稍候...
BAIJIA HOT
LOCAL NEWS
您所选城市新闻不足,将展示省会新闻
正在加载,请稍候...
国际热搜词
Entertainment
日,东风风神AX3正式上市。这款车...
正在加载,请稍候......
互联网图片
互联网+图片
Technology
社会新闻排行榜
百度新闻独家出品
新闻由机器选取每5分钟自动更新
百度新闻搜索源于互联网新闻网站和频道,系自动分类排列,百度不刊登或转载任何完整的新闻内容站内网址搜索
本页最后更新: 14:57:28
【欢迎来到:《船讯网》】
网站分类:
网站名称:
网站地址:
站长邮箱:
站长QQ:
收录时间:
报告错误:
欢迎来到:《船讯网》已报错(0)次,打不开请
收录查询:
数据统计:
今日点入:0 总点入:0 总点出:0
网站简介:
船讯网是一个免费的实时查询船舶动态的公众服务网站。能够为船东、货主、船舶代理、货运代理、船员及其家属,提供免费的船舶实时动态,能给船舶安全航行管理、港口调度计划、物流、船代、货代带来极大的方便。该网站是通过AIS,Inmarsat-C, inmarsat D+ 等各种方式获得的船舶动态位置,利用大众互联网的WebGis技术,直观、方便的将这些信息显示在电子海图上。无论使用者身在何处,办公室、咖啡厅、机场,只要能通过电脑或者手机上网,就可方便、快捷的访问船讯网,查询到全球船舶的实时动态。 船讯网是采用的分布式计算和群集技术,主要的系统架构分为船舶数据服务器,海图服务器,船舶数据处理服务器,客户服务器。   船舶数据服务器,用来存储从来自全球各地AIS接收到的船舶实时动态数据。服务器自动将二进制的AIS数据流,通过标准的AIS协议,转换成可读的数据存储在服务器中。当某个用户在前台页面请求时,船舶数据服务器自动响应,将船舶位置更新至最新。   海图服务器,用来存储和处理海量海图数据。该服务器采用标准的GIS架构,将全球海图分为18级,并将瓦片化的海图数据按照一定的规则分别存储。当有用户请求时,服务器自动将请求的海图瓦片传输至用户电脑,下载到用户本地缓存,以便下次访问更加快捷。   船舶数据处理服务器,用来处理每天收到的海量船舶动态数据。   客户服务器,用来存储客户的资料、定制、权限、到港提醒、短信收发、卫星D+通信等内容。电话:010-
【最新来访网站】
?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&
【相关点出网站】
?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&
免责声明:888导航以上所有广告内容均为赞助商广告提供,对其经营行为本网站恕不负责。Copyright&
All Right Reserved
强烈建议使用 IE5.0 以上浏览器 分辨率 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
静态查找表及查找算法顺序查找折半查找动态查找表及查找
下载积分:800
内容提示:静态查找表及查找算法顺序查找折半查找动态查找表及查找
文档格式:PPT|
浏览次数:40|
上传日期: 06:43:06|
文档星级:
该用户还上传了这些文档
静态查找表及查找算法顺序查找折半查找动态查找表及查找
官方公共微信两个表的表结构设计是一样的,一个字段作为主键,通过什么方式可以查找出两个表中存在的不同的记录,并把主键显示出来?
[问题点数:40分,结帖人frustrate2]
两个表的表结构设计是一样的,一个字段作为主键,通过什么方式可以查找出两个表中存在的不同的记录,并把主键显示出来?
[问题点数:40分,结帖人frustrate2]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2011年8月 总版技术专家分月排行榜第三
2012年10月 荣获微软MVP称号2011年10月 荣获微软MVP称号
2011年8月 总版技术专家分月排行榜第二2011年7月 总版技术专家分月排行榜第二
2012年7月 荣获微软MVP称号
2011年3月 其他开发语言大版内专家分月排行榜第三
2011年 总版技术专家分年内排行榜第四2010年 总版技术专家分年内排行榜第九2009年 总版技术专家分年内排行榜第八
2011年10月 总版技术专家分月排行榜第一
2011年8月 总版技术专家分月排行榜第二2011年7月 总版技术专家分月排行榜第二
2012年7月 荣获微软MVP称号
本帖子已过去太久远了,不再提供回复功能。各式结构化数据 动态 接入-存储-查询 的处理办法 (第二部分) - JAVA编程语言程序开发技术文章 - 红黑联盟
各式结构化数据 动态 接入-存储-查询 的处理办法 (第二部分)
各式结构化数据的动态接入存储查询,这一需求相信有很多人都遇到过,随着实现技术路线选择的不同,遇到的问题出入大了,其解决办法也是大相径庭。数据存储在哪儿,是关系型,还是NoSQL数据库,是MySQL还是Oracle,怎么建立索引,建立什么类型的索引,都是大学问。下面,我要把我对这一解决办法的思考总结一下,有成熟的也有不成熟的,希望大家一起共同探讨。
关键词:结构化数据, 动态, 接入, 存储, 查询
首先,我们得定义一下在本文中什么是结构化数据,这里的结构化数据主要是指扁平化的、可以由基础数据类型组合成的数据,例如:{&data&:{&name&:&wang anqi&,&age&:28,&money&:1653.35,&XX_date&:&&}},它们是可以很容易被存入关系型数据库的,我们要讨论的就是这种数据。对应的,非结构化数据这里是指那些需要存储在文件系统中的,不是扁平化的数据。
那么,什么又是&各式结构化数据&呢,在本文中?这是一个数据集合,有可能集合中的每一条数据结构都是不尽相同的,例如:{&data&:{&name&:&wang anqi&,&age&:28,&money&:1653.35,&XX_date&:&&}},和{&angel&:{&address&:&清凉山公园&,&user&:}}同时存在于一个数据集合中,它们结构不同,简单地说:第一条数据有四个属性,第二条数据只有两个属性,属性名称和类型都不一样。&各式&包括了不定数量的属性,不定的属性名称、不定的数据类型。
解释清楚名词了,再解释一下动词:&动态接入&。在普遍情境下,你只会遇到将固定数据结构的数据存储入库,这里的入库主要还是指MySQL一类的关系型数据库。那么你可以选择使用Hibernate等ORM工具或不使用,来进行数据的存储读取,在使用ORM工具的情况下,要首先定义好数据的数据结构,写死在xml里或是java代码里。
一般情况下,你是不会遇到这样的需求的:对于不能事先确定数据结构的数据,我要把它们存储到关系型数据库中,并提供&合法性检验&、&更新&、&查询&等基本数据操作。要说的是,如果要把它们存储到HBase这种NoSQL数据库中,那是再好不过的了,配合着HBase与Solr的集成(详见之前的博客:大数据架构-使用HBase和Solr将存储与索引放在不同的机器上 /wgp13x/p/3927979.html),搜索也不是件难事,唯一可能出现的难点在于:Solr对于Schema中filedName的配置,因为结构是动态的,所以fildName也是动态的,这其实也是很好处理的,有位微软的同学已经跟我咨询过这个问题了;事实上,这样的例子是很常见的。
但是往往,事与愿违,很有可能存在着其它的约束条件制约着你:必须使用关系型数据库,那么一整套解决办法是需要设计的。因为当你使用Hibernate时,你不能再把一个数据结构写死在代码里,因为它不是固定的,你该如何入库,该如何查询数据,这都是问题。
要处理好&各式结构化数据动态接入管理&,应该分成以下几步:一、定义数据;二、动态管理;三、数据接入;四、数据查询。其中一二步在之前的博客
各式结构化数据 动态 接入-存储-查询 的处理办法 (第一部分)/wgp13x/p/4019600.html 中已经说明。
三、数据接入
因为相关数据提供者可能很多,他们的存储机制、传输方式、使用语言也都不一样,但是需要让他们提供成一致的数据格式,这就需要跟他们协商好一个统一的接口来进行数据解析。在这里我设计了一个统一的数据格式来进行数据接入,即在接入前将各种数据一致化。我采用的是Json定义的通用数据结构,使用Jackson来进行解析,具体的使用方法还需察看我之前写的一篇博客:
使用Json让和C#沟通的方法 /wgp13x/p/0effafd9f5283cbf36e62b4fb5e94c81.
下面的就是我定义的Datas数据结构,它按照《基础数据定义文档》(见博客: 各式结构化数据 动态 接入-存储-查询 的处理办法 (第一部分)/wgp13x/p/4019600.html
)屏蔽了如int、string、date等数据类型,在colummns中可以说明数据中各字段的数据类型,也可以省略这一colummns说明;在data中,统一把数值转化为string类型。
&* @author 王安琪
&* @since 下午4:13:07
public class Datas implements Serializable
& & @JsonProperty(&dataType&)
& & private String dataT//数据类型名称
& & @JsonProperty(&columns&)
& & private Map&String, String&//这里可以为空,属性名-属性类型 键值对
& & @JsonProperty(&datas&)
& & private List&Data&//多行数据
&* 一行数据
&* @author 王安琪
&* @since 下午2:16:06
public class Data implements Serializable
& & @JsonProperty(&data&)
& & private Map&String, String&//属性名-属性值 键值对
好了,传入的数据就像这样:{&dataType&:&angel&,&datas&:[{&data&:{&name&:&wang anqi&,&age&:28,&money&:1653.35,&XX_date&:&&}},{&data&:{&name&:&王安琪&,&age&:28,&money&:16533.5}}]}。为简便起见,这里省略了columns属性。
在这一步需要产生一个文档《统一数据格式定义》,共享给各&干系人&,毕竟数据是可能是由其它部门、其它人提供的,他们依据这里的定义来产生规定格式的数据。
我们接收到数据后,就要依次进行下面的操作了:1、数据格式验证;2、数据入库;3、执行其它业务逻辑。
数据格式验证可以通过在属性表(TBL_ATTRIBUTE)中配置的属性约束正则表达式,来保证接入数据的正确性,它还是比较容易的,较难的是,判断完成后进行的后继操作。比如:一条数据中,只有一列下的数据格式验证不正确,则应该如何处理,是整条丢弃还是这一列的数据内容丢弃,还是其它的方案......后继操作的选择,是由你的业务需要来确定的,通常与技术无关,这时,你就需要拿起电话跟你的&干系人们&进行沟通了。
数据入库,我使用的是直接拼SQL语句,sql = &insert into ** values ***&,SQLQuery query = session.createSQLQuery(sql.toString()); query.setProperties(data); query.executeUpdate(); 这样的方式来入库的,表建立起来了,入库还是比较简单的。
四、数据查询
数据查询也要做得很灵活,因为数据结构不定,因此查询条件也不定。数据查询经常需要,对所有类型的数据,它所有的属性,进行 (包含)like 或 (等于)= 或 (大于)& 或 (小于)& 等等条件的查询,甚至还有可能进行组合查询,如(或者)OR (并且)AND,以及它们的嵌套。从查询条件的数据结构来看,它是一个树型结构数据。
动态查询条件,相信很多人在项目中有这样的需要。
为此,我设计了一个统一的查询条件的格式,前端提交的查询条件都需要遵循它。它同样采用Json来定义,使用Jackson来解析。定义的各类如下所示,Addable 是一个空接口,里面没有任何方法。
&* 查询条件
&* @author 王安琪
&* @since 下午3:45:23
public class Search implements Serializable
& & @JsonProperty(&area&)
& & private List&String&
& & @JsonProperty(&order&)
& & private O
& & @JsonProperty(&condition&)
& & private C
&* 查询排序条件
&* @author 王安琪
&* @since 下午4:03:46
public class Order implements Serializable
& & @JsonProperty(&front&)
& & @JsonProperty(&end&)
& & @JsonProperty(&sequences&)
& & private Map&String, String& // &age&, &desc&; &name&, &asc&
&* 查询约束组合
&* @author 王安琪
&* @since 下午4:04:41
public class Condition implements Addable, Serializable
& & @JsonProperty(&relation&)
& & private S
& & @JsonProperty(&terms&)
& & private List&Term&
& & @JsonProperty(&conditions&)
& & private List&Condition&
&* 单一查询约束
&* @author 王安琪
&* @since 下午3:45:39
public class Term implements Addable, Serializable
& & @JsonProperty(&field&)
& & private S
& & @JsonProperty(&type&)
& & private S
& & @JsonProperty(&oper&)
& & private S
& & @JsonProperty(&values&)
& & private List&String&
传入的查询条件就像这样:{&area&:[{&angel&}],&condition&:{&terms&:[{&field&:&age&,&type&:&int&,&oper&:&between&,&values&:[&28&,&48&]}]}},需要注意的是oper字段的内容,它也是事先定义好的,你需要跟你的&干系人&们协商好可能存在的查询操作符,相关业务需求可能已经规定好了你的查询的可能性,比如对于数据型要有大于小于等于,字符串型要提供有(包含)like 或 (等于)等,日期型要有(大于)& 或 (小于)& 等,这一步,你也需要产生一个文档《数据查询条件定义》。
光设计好了查询条件格式还远远不够,你肯定需要将它解析,继而用它来进行数据库查询,因为这里用的是关系型数据库,所以要把它转成一个SQL语句。下面是各类中实现这一功能的代码段。这里为简化,没有把排序条件order写出。
Term 类 Term 类
& & &* 将Term转变为SQL语句
& & &* @return SQL语句
public String toSQL()
& & & & StringBuilder sql = new StringBuilder();
& & & & String valuesSQL = getSqlValues(type, oper, values);
& & & & String sqlOper = getSqlOper(oper);
& & & & sql.append(field).append(& &).append(sqlOper).append(& &)
& & & & & & .append(valuesSQL);
& & & & if (sqlOper.equals(&like&))
& & & & & & sql.append(& ESCAPE '!'&);
& & & & return sql.toString();
private String getSqlValues(String type, String oper, List&String& values)
& & & & StringBuilder sqlValue = new StringBuilder();
& & & & if (values.size() == 1)
& & & & & & sqlValue.append(getSqlValue(type, oper, values.get(0)));
& & & & else if (values.size() & 1)// between
& & & & & & for (String value : values)
& & & & & & {
& & & & & & & & sqlValue.append(getSqlValue(type, oper, value)).append(& and &);
& & & & & & }
& & & & & & sqlValue.delete(sqlValue.length() - 5, sqlValue.length());
& & & & return sqlValue.toString();
private String getSqlValue(String type, String oper, String value)
& & & & StringBuilder sqlValue = new StringBuilder();
& & & & value = StringEscapeUtils.escapeSql(value);
& & & & sqlValue.append(&'&);
& & & & switch (oper)
& & & & case &like&:
& & & & & & sqlValue.append(&%&).append(escapeLikeSql(value)).append(&%&);
& & & & & &
& & & & default:
& & & & & & sqlValue.append(value);
& & & & & &
& & & & sqlValue.append(&'&);
& & & & return sqlValue.toString();
private String escapeLikeSql(String likeValue)
& & & & String str = StringUtils.replace(likeValue, &!&, &!!&);
& & & & str = StringUtils.replace(str, &%&, &!%&);
& & & & str = StringUtils.replace(str, &*&, &!*&);
& & & & str = StringUtils.replace(str, &?&, &!?&);
& & & & str = StringUtils.replace(str, &_&, &!_&);
private String getSqlOper(String oper)
& & & & String sqlO
& & & & switch (oper)
& & & & case &like&:
& & & & & & sqlOper = &like&;
& & & & & &
& & & & default:
& & & & & & sqlOper =
& & & & & &
& & & & return sqlO
Condition 类 Search 类
& & &* 产生SQL语句
& & &* @return SQL语句
public String toSQL()
& & & & StringBuilder sql = new StringBuilder();
& & & & String rlt = (relation == null || relation.isEmpty()) ? Constants.SQL_AND
& & & & & & :
& & & & if (terms != null)
& & & & & & for (Term term : terms)
& & & & & & {
& & & & & & & & sql.append(&(&).append(term.toSQL()).append(&)&).append(rlt);
& & & & & & }
& & & & & & sql.delete(sql.length() - rlt.length(), sql.length());
& & & & if (conditions != null)
& & & & & & for (Condition condition : conditions)
& & & & & & {
& & & & & & & & sql.append(&(&).append(condition.toSQL()).append(&)&)
& & & & & & & & & & .append(rlt);
& & & & & & }
& & & & & & sql.delete(sql.length() - rlt.length(), sql.length());
& & & & return sql.toString();
public String toSQL()
& & & & if (this.condition == null)
& & & & & & return &1 = 1&;
& & & & return this.condition.toSQL();
通过调用Search.toSQL()拿到使用以上代码生成的SQL查询条件语句后,你就可以使用Hibernate提供的
Query query = m_sessionFactory.getCurrentSession().createSQLQuery(sql.toString()).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); & & & &List result = query.list(); 来进行数据库查询了,你甚至可以依照《统一数据格式定义》中定义的Datas类型,来生成一个Datas对象。
List&Data& datas = new ArrayList&Data&();
for (Object oResult : result)
& & & & & & Map mResult = (Map) oR
& & & & & & Map&String, String& values = new HashMap&String, String&();
& & & & & & for (Object o : mResult.keySet())
& & & & & & {
& & & & & & & & if (o == null || mResult.get(o) == null)
& & & & & & & & {
& & & & & & & & & &
& & & & & & & & }
& & & & & & & & String name = String.valueOf(o);
& & & & & & & & Object vo = mResult.get(name);
& & & & & & & & S
& & & & & & & & {
& & & & & & & & & & value = String.valueOf(mResult.get(name)).trim();
& & & & & & & & }
& & & & & & & & if (value == null || value.equals(&&))
& & & & & & & & {
& & & & & & & & & &
& & & & & & & & }
& & & & & & & & values.put(name, value);
& & & & & & }
& & & & & & Data data = new Data(values);
& & & & & & datas.add(data);
Datas ret = new Datas(search.getArea().get(0), null, datas);
1、大数据查询问题
如果,你要接入的数据量巨大,现在经过以上的步骤,也都正确存入了关系型数据库中了,可能一张表中存储了千万级的数据,现在提交了一次查询请求,这下好了,这次查询请求连接到数据库查询数据占用了十来分钟的时间(这跟查询条件有关,对于查不到的数据,查询就很慢),也就是说十多分钟后此链接才能释放,那么问题来了,如果你多提交了几次这样的查询请求,只有十次,数据库就卡死了,大量的链接Client Connections停滞在Sending data和Statistics状态,再来多少请求,无论是占长时间的查询还是很短时间就能处理的查询,统统都不能立即返回结果了,用户直接的反应就是你的后台不工作了,虽然耐心等待十多分钟后还能正常查询。
处理办法:
a、建立索引。因为是各式结构化数据动态接入,所以对所有的数据表,所有的字段,根据不同的数据类型,需要建立(不同的)索引,这很繁琐,而且索引占用磁盘空间,经过测试,索引建完后,查询速度是提升了不少,但仍不可接受。这是一个大问题,也许对于大数据,也许经过MySQL的性能优化能够稍微好些,但MySQL能做的只有这了。你有什么好的调优手段?
b、悬而未决,你的建议。
2、Date类型转化问题
通过Transformers.ALIAS_TO_ENTITY_MAP查询出来的结果,value = String.valueOf(mResult.get(name)).trim();结果对于日期、时间类型的数据都是Date类型的,数据库中的时间可能是yyyy-MM-dd HH:mm:ss样式的,然而value却是 15:50:30.0这样的,精确度不一致,用户也有意见。
处理办法:
a、悬而未决,你的建议。

我要回帖

更多关于 动态存储 的文章

 

随机推荐