轨迹管理系统平常生活中使用很是广泛,如外卖派送轨迹、快递物流流转、车辆定位轨迹等。该场景与地理位置管理相似,核心点与瓶颈都在数据库的存储性能与查询能力,同时须要时间字段正序排列,保证轨迹点顺序;一方面,存储服务须要应对海量数据的低延迟存、读,另外一方面,存储服务也要提供高效的多维度数据检索与排序。表格存储(TableStore)对于轨迹管理场景,依然能够胜任,彻底具有实现轨迹管理系统的能力。
不妨来体验一下基于TableStore打造的【亿量级摩托车管理系统】样例;html
某城市市区出于安全考虑,限制摩托车进入必定的区域范围。某摩托车租赁公司,为了更好管理所辖摩托车的违章问题,对本身所辖摩托车安装定位系统,定时采集摩托车位置。摩托车租赁公司,能够经过轨迹管理平台,查询统计违章状况,也可做为依据,提醒违章的租赁用户,过多违章拉入黑名单;
查询场景:【2018年11月01日】编号【id00001】的摩托车行驶轨迹与违章状况查询;java
样例以下:
注:该样例提供了【亿量级】轨迹数据。官网控制台地址:项目样例node
样例内嵌在表格存储控制台中,用户可登陆控制台体验系统(若为表格存储的新用户,须要点击开通服务后体验,开通免费,订单数据存储在公共实例中,体验不消耗用户存储、流量、Cu)。git
采用表格存储(TableStore)轻松搭建一套:亿量级摩托车管理系统。多元索引功能提供GEO检索、多维查询的能力,经过对时间的排序获取追踪设备的轨迹。同时,用户可随时建立索引而后完成自动同步,不用担忧存量数据问题。
TableStore做为阿里云提供的一款全托管、零运维的分布式NoSql型数据存储服务,具备【海量数据存储】、【热点数据自动分片】、【海量数据多维检索】等功能,有效的地解决了GEO数据量大膨胀这一挑战;
SearchIndex功能在保证用户数据高可用的基础上,提供了数据多维度搜索、排序等能力。针对多种场景建立多种索引,实现多种模式的检索。用户能够仅在须要的时候建立、开通索引。由TableStore来保证数据同步的一致性,这极大的下降了用户的方案设计、服务运维、代码开发等工做量。github
若您对于基于TableStore实现的【亿量级摩托车管理系统】体验不错,并但愿开始本身系统的搭建之旅,只需按照以下步骤即可以着手搭建了:数据库
经过控制台开通表格存储服务,表格存储即开即用(后付费),采用按量付费方式,已为用户提供足够功能测试的免费额度。表格存储官网控制台、免费额度说明。安全
经过控制台建立表格存储实例,选择支持多元索引的Region。(当前阶段SearchIndex功能还没有商业化,暂时开放北京,上海,杭州和深圳四地,其他地区将逐渐开放)运维
建立实例后,提交工单申请多元索引功能邀测(商业化后默认打开,不使用不收费)。分布式
使用具备多元索引(SearchIndex)的SDK,官网地址,暂时java、go、node.js三种SDK增长了新功能性能
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>tablestore</artifactId> <version>4.7.4</version> </dependency>
$ go get github.com/aliyun/aliyun-tablestore-go-sdk
店铺检索系统样例,仅简易使用一张店铺表,主要包含字段:店铺类型、店铺名称、店铺地理位置、店铺平均评分、人均消费消等。表设计以下:
表名:geo_track
列名 | 数据类型 | 索引类型 | 字段说明 |
---|---|---|---|
_id(主键列) | String | MD5(mId + timestamp)避免热点 | |
mId | Stirng | 摩托车编号 | |
timestamp | long | LONG | 时间点(毫秒时间戳) |
pos | String | GEO_POINT | 车辆位置:"30.132,120.082"(纬度,精度) |
... | ... | ... | ... |
用户仅需在完成邀测的实例下建立“摩托车轨迹表”:经过控制台建立、管理数据表(用户也能够经过SDK直接建立):其余表如租赁用户表、摩托车信息表等,根据需求建立:这里仅展现轨迹表,表名:geo_track
TableStore自动作全量、增量的索引数据同步:用户能够经过控制台建立索引、管理索引(也能够经过SDK建立索引)
插入部分测试数据(控制台样例中插入了1.08亿条(1万辆摩托70天24小时*6个"10分钟点")数据,用户本身能够经过控制台插入少许测试数据);
表名:geo_track
摩托车编号 | 轨迹点md5(mId + timestamp)(主键) | 时间 | 店铺位置 |
---|---|---|---|
id00001 | f50d55bec347253c24dc9144dff3e3b7 | 1541103600000 | 30.30094,120.01278 |
表名:moto_user
摩托车编号(主键) | 摩托车颜色 | 摩托车品牌 | 摩托车租赁用户 |
---|---|---|---|
id00001 | 银灰色 | H牌摩托车 | 杨六 |
数据读取分为两类:
基于原生表格存储的主键列获取:getRow, getRange, batchGetRow等。主键读取用于索引(自动)反查,用户也能够提供主键(摩托车编号)单条查询的页面,查询速度极快。单主键查询方式不支持多维度检索;
基于新SearchIndex功能Query:search接口。用户能够自由设计索引字段的多维度条件组合查询。经过设置选择不一样的查询参数,构建不一样的查询条件、不一样排序方式;目前支持:精确查询、范围查询、前缀查询、匹配查询、通配符查询、短语匹配查询、分词字符串查询,并经过布尔与、或组合。
如【2018年11月01日,id00001号摩托车,行驶轨迹及违章查询】Query条件以下:
List<Query> mustQueries = new ArrayList<Query>(); List<String> polygonList = Arrays.asList(//地理围栏,禁摩区域 "30.262348,120.092127", "30.311668,120.079761", "30.332413,120.129371", ... ); String mId = "id00001"; Long timeStart = [2018-11-01时间戳]; Long timeEnd = [2018-11-02时间戳]; GeoPolygonQuery geoPolygonQuery = new GeoPolygonQuery(); geoPolygonQuery.setPoints(polygonList); geoPolygonQuery.setFieldName("pos"); mustQueries.add(geoPolygonQuery); TermQuery termQuery = new TermQuery(); termQuery.setFieldName("mId"); termQuery.setTerm(ColumnValue.fromString(request.getmId())); mustQueries.add(termQuery); RangeQuery rangeQuery = new RangeQuery(); rangeQuery.setFieldName("timestamp"); rangeQuery.setFrom(ColumnValue.fromDouble(timeStart, true); rangeQuery.setTo(ColumnValue.fromDouble(timeEnd, false); mustQueries.add(rangeQuery); BoolQuery boolQuery = new BoolQuery(); boolQuery.setMustQueries(mustQueries);