目录
gecko.NET Library and Web Service
General Cartographic Transformation Package - JavaScript
InterMap:InterMap是一个互联网地图应用,允许用户通过分布式的互联网地图服务器在浏览器中共同交互地图。
Portfolio Explorer Open Source
rmap:这个封装派生自在地球上进行正确经纬定位的个人地图系统需要。与CIA第二数据银行包含39轨磁带的COBAL数据建立了关联,它们运行在陈旧的主框架,也还有像样的地球矢量数据,也可以在公共域运行。
PostgreSQL10版本与9.6版本to_tsvector函数的差异
几何类型和GIS
GIS 系统
3map
行星地球项目由3map驱动,这是一个自由软件,由Telstra宽带基金会创建并支持,提供客户端与服务器的能力以在线再现虚拟地球。
## Amein!
其界面介于ArcMap和UMN Mapserver之间.AmeiN!写了一个ArcMap下的扩展,把UMN Mapserver写成了ArcMap的一个组件,同时也编写了它的项目文件,转换了它的许多实例。
APR Parser
与ArcView协同工作,引导包含了众多项目、表单、视图等的海量文件获取和存放。由于获取的复杂性,几乎不可能看到这些表单间所有的链接。一个数据库包括了所有的帮助定位数据和加速搜索的信息。
ArcGIS
ArcGIS是Esri公司集40余年地理信息系统(GIS)咨询和研发经验,奉献给用户的一套完整的GIS平台产品,具有强大的地图制作、空间数据管理、空间分析、空间信息整合、发布与共享的能力。ArcGIS不但支持桌面环境,还支持移动平台、Web平台、企业级环境、以及云计算架构。ArcGIS同时为开发人员提供了丰富多样、基于IT标准的开发接口与工具,让您轻松构建个性化的GIS应用。
AutoREALM
是一款自由的GNU作图软件。它可以用于设计城堡、城市、地下城等的地图。AutoREALM主要被用于角色扮演游戏的自定义地图。但也可以用于更多人群。
AVCE00
是开源的ANSI C库,能够使Arc/Info矢量图形显示为E00格式。它允许你像处理E00一样读写这些二进制文件。
AvisMap[1]:AvisMap公司提供免费的地图浏览器,GIS开发包以及桌面制图软件。
AVPython
AVPython在ArcView GIS里内嵌了一个Python程序语言。借此,我们可以突破大部分互操作性、可扩展性的障碍,连草根开发者也可以构建现代化的应用。
BASINS
BASINS是一个结合了地理信息系统的多目标环境分析系统,全国水流域数据,艺术视角的环境评估和洲级建模工具。
Batik
BBBike
BBBike是一个柏林和勃兰登堡的自行车人信息系统。这个应用可以:1)显示地图的街道、铁路、河流、公园、海拔高度和其他功能。2)查找并显示航线两点。路线查询可自定义,以符合骑行最优条件(最快或最好的路线,保持风向和计算丘陵等)。3)自行车功率计算器。4)自动获取当前柏林气象数据。
BLM
GIS公用事业,土地局的GIS事业站点。
BRL CADl
BRL-CAD包是一个功能强大的构造实体几何(CSG)的实体造型系统。
BuddySpace
BuddySpace是一个有四个主要功能的即时信使:
- 除了标准的“好友名单”,它还允许可选地理地图和办公室计划可视化;
- 它建基于开源Jabber,使其可以与ICQ、MSN、Yahoo等聊天;
- 它在Java执行,因此是跨平台的;
- 它是由英国一家实验室建立,所以100%开源且完全可用。
CAVOR
CAVOR是一个涉及建模和检索图形与文字资料的引擎。应用广达GIS(地理信息系统),测绘程序,计算机辅助设计,以及不太显眼的项目管理(想想PERT的图表),CASE(计算机辅助软件工程),工具(DFDs、ERDs),以及尚未被利用的功能。
CGAL
计算几何算法库是几个欧洲站点的一次合作尝试。其目标是把最重要的解决方案和方法开发成计算几何,以C++库的形式提供给工业界和学术界用户。
cgList
载列了计算几何的程序和软件包。
Chameleon
Chameloen技术是网页地图领域一项革命性的进步,由DM Solutions开发,旨在创建高度定制化和适应性的环境,部署和管理网页地图应用。
Cocoon ArcIMS:使用Apache Cocoon在ArcIMS上执行wrapper。
Community Mapbuilder:使命是使社区合作使用基于标准的,开放源码的工具建立并分享地理数据。为基于浏览器的地图饰件开发开源的mapbuilder库。
Computer Vision Library
建立开源视图社区,提供网站来结合和更好地执行社区贡献的成果。参见this Computer Vision List。
DCMMS
基于网络的上下水网络维护管理系统。允许存储客户投诉和问题工作顺序表。更多用地图和地标而不是街道名称来导航。使用PostGIS。
Deegree
Deegree是一个Java框架地统计功能解决方案。基于公共地理标志标准,允许建设应用和空间参照内容。Deegree组件可用于建立一个独立的本地安装的桌面绘图解决方案,或设立一个高度分布的和服务为本的架构。
Demeter Terrain Engine
Demeter是一个跨平台C++库,用OpenGL渲染3D地形。Demeter组件为快速性能和良好视觉质量设计,并利用先进技术,如动态镶嵌(自适应网格),实时渲染广域地物,而不需要高端硬件。以独立组件编写而可轻松嵌入任何应用。
DEM Tools
这个包有助于预览DEM(数字高程模型)数据集和在这个星球的不同位置漫步虚拟时空。
DEMViewer
DEMViewer是一个Java编写的数字高程模型看图器。利用它你可以可视化ArcInfo生成的数字高程模型(如ASCII文件)并接合数据(照旧使用ArcGrid ASCII输出格式和/或JPG/PNG/GIF图像格式)。
DGNLib
DGNLib是MicroStation的DGN(ISFF)阅读器。
Discovering Cambodia
这个网站提出了一个网络地图服务的开源GIS解决方案,原为开发在线互动地图原型,以通过地图和事实发掘柬埔寨。
dlgvu
dlgvu是一个Unix的互动数字线划图(DLG)看图器,用Icon程序语言书写。
drawmap
Drawmap是制图封装,使用来自美国地质调查局(USGS)的数据绘制地图。大部分的USGS数据是美国范围内的,但GTOP30数据已覆盖全球。地图输出采用SUN的rasterfile图片格式。
E-FOTO
这项工作旨在建立一条研究线索,涉及了数字摄影测量例程的计算发展,使用高级语言,目的是发展教学用的数字摄影测量工作站。
EDBS
德国地形数据传输标准EDBS/ATKIS格式及其阅读器。由于这种数据格式的天然属性,信息全部都是德文。
ElectricArc
一种通用图形编辑器,它按照方便程度,把图画应用概略限制成不同等级。ElectricArc可以被用于设计从抽象图到电路图、数据库架构、计算机网络乃至代谢途径。
FeatureX
FeatureX项目的目标是建设一个自主、互动的特征提取封装,最终将被集成到OSSIM项目。
FIST
柔性互联网空建模版(FIST)是一个开源的,超文本预处理器(PHP)基于对象的应用,用于快速部署互联网地图网站。
FlightGear
FreeType
FMaps
FMaps是一个地理信息系统和遥感应用,数据存储在PostgreSQL数据库。它使用一种特殊的GTK+工具,最初称为GtkFMaps。
FREEDraft:FREEdraft是一个项目,以创建一个简单的二维机械CAD系统。
Fulcrum
Fulcrum是一个自由的Java库,其中包括用户界面组件、数据模型,和有用的实用程序来帮助Java开发者建设分布式地图应用。Fulcrum库还可用于其它目的,当前攻关的是创建通过网络消费地图数据的应用。数据源可以是独立的开放源,也可以是商业的地图服务器,还可以是更加复杂的,如开放地理空间协会网络服务。
FWTools
FWTools是一套用于Windows(win32)和Linux (x86)的开源GIS二进制文件,作者是Frank Warmerdam。以前称为OpenEV_FW。这套文件的目的是便于用户安装和入门的。无需从源编译,或是收集大量相互关联的软件包。FWTools包括了OpenEV、GDAL、MapServer、PROJ.4和OGDI以及一些辅助部件。
G - H
GARNIX
GARNIX是一个通信程序,它提供了MS-DOS计算机和Garmin公司GPS设备之间的数据接口。
GD
一个速成图像的图形库。
GDAL
GDAL是一个转换库,用于栅格地统计数据格式,在开放源码协议下发布。作为一个库,它为所有支持的格式提出了统一的行业应用抽象数据模型。
GDV Mapserver Client
用Javascript写就的Mapserver网络客户端。
gecko.NET Library and Web Service
gecko.NET是一个自由、开源、原生的.NET框架地理信息系统地图网络服务、可视化控制和库,用于支持.NET用户控制和库的软件开发环境。你可以将gecko.NET用于以Visual Basic .NET、C Sharp和任何支持.NET平台的语言所写的应用。
geGIS
geGIS是一个基于WMS、WMS和SOAP服务的地理电子服务框架。客户端是一个瘦客户端浏览器应用,可以可视化和编辑提交数据。它其实就是一个定制的XML。
gen2shape
Gen2shp是一个简单的C程序,可以读取ArcInfo生成命令所要求的数据。在这个文件中的数据将被转换为shapefile格式,也就是.shp,.shx和.dbf。
General Cartographic Transformation Package - Fortran:通用制图转换包(GCTP)是一个软件系统,常规地被设计成允许从一幅地图影射到另一幅的坐标变换。
General Cartographic Transformation Package - JavaScript
通用制图转换包-JavaScript版(GCTP-JS)是开源JavaScript指令集,用以提供动态的、从互联网应用到客户端的坐标变换。它提供了一定数量的坐标之间的变换能力,包括Lambert、亚尔勃斯投影、UTM等。
GEO
GEO是一个脚本坐标变换工具。
Geocoder
这是2002年Google程序大赛的作品。包括一套地理编码(使用TIGER/Line将街道地址转换为经纬度坐标),一部简单的地址和关键字索引,以及一款查询引擎,来搜索匹配的文件以至距目标位置一定距离以内的地址。
geocoder.us:一种在美国提供的公共服务,包括门牌和路口的免费地理编码,地理编码服务基于Geo::Coder::US,可从CPAN下载一个Perl模块。
GeoCommunity
Geocom的收集翻译工具的页面。
GEODAS
GEODAS(地球物理数据系统)是国家地球物理数据中心(NGDC)开发的一个交互式数据库管理系统,用于消化、储存和检索地球物理资料。
GeoIP API
GeoIP是一个根据IP地址查询位置的API的集成。它支持对国家、地区、城市、纬度和经度的查询。
GeoJasPer
GeoJasPer是一个自由、开源和地理支持的命令行JPEG2000转换器,亦即,在两种地理信息格式GeoTiff和GeoJp2之间进行图像转换。
GeoKettle
GeoKettle是一个“空间可用”版本的Pentaho数据集成(Kettle)。Pentaho数据集成(Kettle)是一个功能强大的、元数据驱动的ETL(抽取、转换和加载)工具,致力于不同数据来源间的聚合。
GeoNetwork OpenSource
一个空间数据元数据的门户网站,实现国际地理元数据标准(ISO19115)和(将要实现)OpenGIS网络目录服务分布式数据库搜索标准。使用应用程序,你可以快速建立元数据门户,允许在线维护元数据和数据,供局域网内部使用或互联网发表。
GeoRuby
GeoRuby从特制的OGC“简单SQL特征”提供几何数据类型。一个铁路插件提供通过透明方式管理PostGIS几何列的功能。
GEOS
GEOS(几何引擎——开源)是一个Java拓扑套件(JTS)的C++移植。因此,它的目的是在C++中包含完整的JTS移植。这包括了所有的OpenGIS“简单SQL特征”:空间预测函数和空间操作员,以及具体的JTS拓扑功能,如IsValid()。
GeoServer
GeoServer项目是一个Java EE实现的OpenGeospatial网络功能服务器规范,由开放规划项目(TOPP)维护。
GeoToad
GeoToad是自由软件,帮助加速乏味的地缓存:选择缓存和收集数据。它是未来地缓存工作者的完美工具。
GeoTools
Geo Tools是自由的基于Java的制图工具包,允许在网页浏览器上交互式浏览地图,而无需专门的服务器端的支持。
Geotools.Net
Geotools.Net是一套.Net类,有助于处理地理信息。该项目始于从Java移植到C#的JTS 1.2。它实现了以下OpenGIS规范:简单功能规范、坐标转换服务。其他功能包括:读写已知二进制文件、输出到SVG、ESRI shapefile格式导入和导出。
GeoVista Studio
GeoVISTA Studio是一个开放的地理空间数据软件开发环境。Studio是一种免编程环境,能使用户快速建立应用进行地理计算和地理可视化。
GeoVRML
GeoVRML是一项使用VRML97(虚拟现实建模语言)为表现和表达地理数据提供支持的尝试。
GeOxygene
空间数据GeOxygene的目的是提供一个开放的框架,实现OGC/ISO的规格,开发和部署地理(GIS)的应用。这是IGN(国家地理研究所),法国国家地图机构的COGIT实验室一个开放源码的贡献。在LGPL协议下发布。GeOxygene基于Java和开源技术,为用户提供可扩展的对象数据模型(地理特征、几何、拓扑和元数据)遵循地理信息领域的OGC规范和ISO标准。开源的Java开发接口支持,GeoAPI项目,已经列入计划。
GFC:GFC,或称地理基础类库,是一套定义基础地理数据类型的C++类,包括点、线、矩形、圆、折线、环、复杂多边形、栅格,及整数、实数、变量等其它原子数据类型。GFC还具有抽象的时间戳和时间序列功能,有助于捕捉动态的时空数据。
Ghostscript
GISAR
GISAR项目是二维、三维实物动态模型(如街道、公路、房屋、电话、客户等),可用于发展实时系统的任何功能和视觉模型。它是地理信息系统的实例,为任何连接的客户端提供实际状况的数据,无论任何时间模型物发生的任何变化。现在它用作自动工作的通讯站。
GIServer
GIServer是从inovaGIS项目创建的,在互联网上提供免费接入GIS的功能。它仅需具有表格功能的一个互联网浏览器(如网景 (浏览器))……
GIS Knoppix
GIS-Knoppix是一份预装GIS软件的Linux Live CD,基于Knoppix。
GISToolKit
GISToolkit软件是一个开源Java工具包,建立空间应用程序。它拥有一些从不同数据源读取和显示数据的功能。
gispython
这是几个基于PROJ.4、GEOS、GDAL/OGR、MapServer和etree XML界面的网络绘图和GIS项目之家。目标是新的连贯性和模块化的核心,地理空间的Python编程。
GIMP
通用制图工具
GML4J
GML4J是一个便利的Java API,与地理标记语言[2]协同作业。GML是一个基于XML的地理信息编码框架,为开放地理空间协会所建议采用。
Gnuplot
Google地球
gpc
一个灵活和高可靠性的多变性设置操作库,与C程序配合,通过comp.graphics.algorithms调用常见问题和美国伊利诺伊大学计算几何页面。gpc库估计在全球拥有数以千计的用户,数以百计的月下载量。
GPSBabel
GPSBabel转换不同格式的途径点、轨迹和路线,无论它是否属于常见绘图格式,如德洛姆、街道和旅游、或Garmin与Magellan上传和下载的GPS格式。
GpsDrive
GpsDrive是一个车载(自行车、船舶、飞机)导航系统。GpsDrive根据你的兼容NMEA的GPS接收机传回的数据在可缩放地图上显示你的位置,地图文件可以依据位置和最佳比例尺自动选择。
GPSMan
GPS管理者(GPSMan)是一个GPS数据图形化管理器,创建一个配置、检查、编辑GPS数据的用户友好界面。GPSMan支持包括台湾国际航电和Lowrance接收机的通讯和实时登陆,也接受任何支持NMEA 0183标准的GPS接收机实时登陆信息。
gpspoint
一个获取位置、从你的GPS机下载上传途径点、路线和轨迹到电脑的程序。
GPStrans
GPStrans与Garmin全球定位系统接收机通讯,允许用户以之上传下载途径点、路线、日历(卫星轨道要素),并跟踪路线。
gpsutils
这个项目的目的是开发开源GPS软件库及应用。兴趣特别集中于开发软件,允许由低成本的OEM单元,如Garmin GPS35 TracPak,对伪距/载波相位数据进行后处理。
GPS3d
GPS3D是一家从PC处理手持GPS设备的程序,和三维可视化结果的集合。即便没有GPS设备,你也可以使用GPS3d来交互式放映三维地球纹理影射模型。
Grace
Grace是一个所见即所得的二维绘图工具,用于X窗口系统和M*tif。
GrADS
格网分析和显示系统(Grads)是一个交互式桌面工具,用于简单获取、处理、可视化地球科学数据。Grads被广泛应用于多种常用操作系统,并在互联网上自由发布。
GRASS
GRASSLinks
GRASSLinks提供环境数据的公共获取。用户仅需一架网页浏览器和互联网接入即可使用其大型空间数据库和REGIS提供的强大的地理信息系统软件,GRASSLinks的目标是提供在环境规划机构、公共行动团体、公民和私营实体之间协同和数据共享的原型。
GSLIB
GSLIB是Geostatistical Software LIBrary(地统计学软件库)的缩写。该名称最早用于15年前斯坦福大学收集地统计程序的项目。
Gstat
Gstat是一个地统计建模、预测和模拟的计算机程序。
GTS Library
GTS代表GNU三角表面库。这是一个开源免费软件库,意在提供一套有用的以网状关联三角形处理三维表面的功能。
Guidebee
引路蜂手机电子地图API,提供手机平台(Java ME等)电子地图API,包括地址查询、路径查询、语音导航等。[3]
gvSIG
Hierarchical Triangular Mesh:分层三角网格(HTM)是一个分割单位球面以为球面三角的分割模式。它是一个分层模式,将下层分成并非绝对,但是大略相等的部分。
HUGO
Hugo是UNIX平台的移动地图软件。Hugo可以以简单栅格(XPM)、矢量和TIFF格式察看地图。ESRI的shape格式支持也在进行中。
HidroSIG
HidroSIG是一个用Java编写的地理信息系统,有一些特殊工具允许做出水文学、气象学、地貌学变量的预测和分析。
I - M
iGeoPortal
这是首次发布的deegree iGeoPortal。Deegree新的客户/门户组件是一个模块化客户端,其配置给予OGC网站地图上下文格式/文书。不同的模块能够提供网页地图客户端功能以及地名词典客户端、目录客户端或WFS客户端的功能。
ImageJ
ImageMagick
Imagine Reader
该阅读器包括一个C++ API,可以阅读任何Erdas Imagine的信息,分层文件、结构文件,以及高水准的将地相关数据向GeoTIFF转换的程序。
InetAddressLocator:快而准确的IP地理位置系统。专家建立。免费分发。
Intergraph WMS Viewer:Intergraph的WMS查看器便利在WMS源中储存的地理空间信息的互通。
InterMap:InterMap是一个互联网地图应用,允许用户通过分布式的互联网地图服务器在浏览器中共同交互地图。
IPW
IPW是一个基于UNIX的图像处理系统。IPW包括了几种 UNIX过滤程序,可被拴在一起以供形成复杂和有力的图像处理运算法则。IPW包括了一个开发环境来用C创建新的IPW的shell脚本和程序。
IrcMarkers
IrcMakers需要一张.png或.jpg格式的地图,和一个坐标列表,和xplanet格式的标签,和地图上的注记。在IRC频道生成用户地图。每个制作者被绑定一个GnuPG/PGP密钥,以创建“可信地图”。
IRIT
IRIT是一个实体建模环境,使人建立基本的、原始的模型,模型使用布尔运算模型和自由曲面模型。
IVICS
IVICS开发成一个可视化工具,以便从卫星图片选择训练样本。它已演变为一种支持几种常见卫星和遥感数据格式的可视化系统。开发了广义卫星格式(GSF)用以支持IVICS。
ivtools
Ivtools是一个X窗口系统的自由的绘图编辑套装,支持PostScript、TeX、网页图形制作,以及一个可嵌入的和可扩展的矢量图形shell。
JasPer
Jasper项目是一个开源创见,提供基于自由软件的由JPEG 2000第一部分标准指定的编解码器之安装参考。
JEEPS
一个GPS软件开发平台。
jGridShift
jGridShift是NTv2转换软件的一小部分。以Java书写,包含了一个J2EE连接架构(JCA)适配器。有一个示例的图形界面工具和一个示例的网络服务。
JCS
JCS酏接套件是一个API以及一组互动工具在空间数据集上执行异文融合。
JTS
Java拓扑套件是一个二维空间谓词和函数的Java API。
JUMP
Java统一映射平台(JUMP)是一个图形用户界面基础的应用,可以查看和处理空间数据。它包括了众多的空间和GIS功能。它也被设计成一个高扩展性框架来开发和运行用户空间数据处理应用。
Kalypso
-Simulation-Platform:Kalypso模拟平台是一款地理空间建模和仿真的开源应用。它优先被开发成一个用户友好的基于GIS的工具,建模和仿真水文学和水力学数字模型。
ka
-Map:ka-Map(ka意味着ka-繁荣)是一个开源项目,旨在为使用现代网页浏览器具有的特性开发高交互性网页地图界面提供JavaScript API。
kdem
kdem是一个显示美国地质调查局(USGS)数字高程模型(DEMs)的程序。
KFLog
KFLog是一项针对滑翔机飞行员的开源项目。它提供有力的工具计划你的飞行任务和事后分析。
KIDS
关键指标数据系统(KIDS)为联合国粮农组织世界农业信息中心(WAICENT)所开发。KIDS是一个软件框架,提供实施专题系统的能力,包括收集、参考、可视化、交流和传播统计、调查和指标数据。KIDS最初被开发用于收集、编绘和传播粮食不安全和脆弱性指标,对应粮食不安全和脆弱信息编绘系统(FIVIMS)。
Kosmo
Kosmo用Java程序语言执行,在JUMP平台下开发,有一个长的序列关于知识和免费代码库,如Geotools和JTS,在自由软件项目中应用广泛。也有来自其它自由软件项目的要素。可用于Windows和Linux操作系统。
kvwmap
kvwmap是一个为电子政务系统设计的复杂的WebGIS客户端和服务器解决方案,写于PHP语言,使用UMN地图服务器技术,MySQL和PostgreSQL/PostGIS数据库,可缩放矢量图形,等等。
LAS
/ADAPS:土地分析系统(LAS)/AVHRR数据采集与处理系统(ADAPS)。
Libgeotiff
一个公共域,读取libtiff头部,书写GeoTIFF信息标签。
libGRASS
libgrass包由大多数GRASS libgis组成,libdatetime库建立为一个独立的共享库,适合希望读写GRASS数据库的非GRASS程序应用。增加了一些额外功能以简化初始化和非GRASS程序的数据访问。当前libgrass仅接受GRASS栅格数据,以及联合支持文件,希望未来版本能够加入对矢量文件,以及其它在GRASS数据库存取的文件的支持。
libTIFF
libXearth
libXearth是Xearth饰件组件。它包含了从constraint继承的earthWidgetClass,是著名的xearth的再现版本。每个儿童针对地理位置和视角(墨卡托或正射)显示。
LIMP
LIMP(大型图像处理程序)开始于一个测试新的图像处理技术的平台。需要大量代码建立高效库以应用任意计算大型数据集(“大”在这里意味着无法完整载入到内存)。LIMP的目标是迁移尽可能多的复杂代码到库里,留下简单而有力的途径处理用户编码图像。
Localis
Localis是一个收费在线绘图工具。它允许你在地图上查看其他用户的附加点,并添加自己的。
LPGS
Lite
LPGS-LITE是一个平台无关(POSIX兼容)的Landsat-7 ETM+数据Level0R到Level1G处理器,由马里兰大学开发。
Lx-Viewer
LX查看器是一个允许你打开、查看、打印DWG或DXF文件的程序,使用AutoCAD关联技术草案。您可以变焦和潘绘图就如在AutoCAD一般。文件可以被存成从AutoCAD2.5到2000版的DWG或DXF格式再加上BMP和PNG。
Majas
MAJAS是一个建设富互联网应用的组成框架,具有先进的显示、分析和管理地理信息的能力。它建立一个模块,允许开发者添加地图和其它适合他们的网页应用的地理数据。一方面,这项产品可以建立像众所周知的Google地图那样的网页地图系统。另一方面,它可以用于构建完整的地理信息系统(GIS)来分析编辑地理数据。它还可以用于为网络应用添加地理数据能力。
Mapbender
Mapbender客户端套件软件包提供用户界面以显示、导航和查询OGC WMS适配地图服务。Mapbender客户端套件还含有用户和组管理端口,并且提供使用网页地图服务存取地图的功能。
MapInfo
Professional
MapIt
MapIt!是一个网络应用,让你通过你的浏览器巡航栅格地图,缩放、选择图上经鉴定的对象和对象类。
MpaJunction3D
第一个基于网络的地图系统,结合了快速的地图显示、航空照片和地理信息。
MapLab
MapLab是一套有效和直观的基于网页的工具,创建和管理MapServer网页地图应用和地图文件。它由三个部分组成:MapEdit、MapBrowser和GMapFactory。
mapnik
Mapnik是一个开源C++/Python工具包用以开发GIS(地理信息系统)应用。其核心是一个C++共享库,提供空间数据获取和可视化的算法/模式。
MapServer
Map
Guide Open Source:开源MapGuide是一个基于网络的平台,支持用户快速开发和部署网页地图应用与地理空间网络服务。
MapServer
Workbench:一套开发MapServer网页地图应用的协作工具。
MapWindow
开源MapWindow GIS项目包含了兼容微软视窗的桌面应用,能够查看shapefile和多种栅格数据格式。它可以通过“GIS工具”插件重生成数据、剪辑、合并,及执行其它地处理。开发用户可以使用任何.NET框架语言书写插件扩展此应用,或使用MapWinGUS ActiveX控制书写GIS软件。
Mapyrus
Mapyrus是一个创建小块点、线、多边形,并标记到PostScript、PDF和网页图像输出格式。该软件结合了以下三个组成部分:Logo图形语言、GIS数据集和RDBMS表阅读器、作为独立程序或网络服务器的运行。
Marble
(KDE)
Maya
2 GoogleEarth:Maya2GoogleEarth是一个开源、跨平台的工具,在Eyebeam开发,从Maya输出三维模型到Google地球。一旦安装,它允许你现场输出3D模型为一个单一的Google地球地标(KML)文件。
MB
-System:MB-System是一个开源的软件包,处理和显示测深和反散射映像数据来源于多波段、干涉、侧声纳。
Mesa
3D
MetaPost
mezoGIS
mezoGIS是一个GIS应用,一个查询和分析空间数据的图形界面。mezoGIS并不直接存储和计算数据,而是调用PostGIS数据库。mezoGIS的目标是通过空中SQL查询和大型外部控件脚本为PostGIS提供一个地理空间分析工具。
微软模拟飞行
MobileMaps
我们把Mobilemaps称为附近引擎但它也叫做“本地网页搜索”,一款“位置搜索引擎”,一种“地可视搜索”,和一个“地图搜索”。它提供独特能力来寻找,如物理接近搜索者指定位置的网页信息,并显示在地图上。它也从地理目标的附近广告提供新的收益。
monoGIS
monoGIS的现阶段目标是于行业认可的Mono平台提供全新完整的GIS系统。
Mozilla
SVG Project:Mozilla SVG实例是一个原生的SVG实例。它不同于插件形式的SVG查看器,如Adobe SVG Viewer。
MP2KML
MP2KML将.mp文件(Garmin IMG地图文件的开放替代格式)转换为.kml文件(Google地球的开放格式)。
MySQL
Spatial:MySQL遵从开放地理空间协会的格式实现的空间扩展。
N - Q
NASA
World Wind
NCAR Graphics
NCAR图形是一个基于Fortran和C的科学可视化软件包。
NetMaps
NetMaps是一个Applet,允许在任何启用了Java的浏览器上看矢量地图。NetMaps可以加载和显示ArcInfo的shape文件(SHP/DBF)和MapInfo的MIF/MID文件。
NetTopologySuite
网络拓扑套件是JTS拓扑套件,GIS操作的Java库(符合OpenGIS)的C#/.NET移植。这一项目的主要目标是提供.NET下的快速可靠的GIS解决方案,包括所有.NET平台,PocketPC和Sql Server 2005(通过通用语言运行库集成)。项目还包括另一些SharpMap的.NET库,集成了从诸如Shape文件格式读写的功能,坐标变换和投影,等等。
NRDB
NRDB是一个GIS工具,用于创建和分发环境数据库。其目的是为发展中国家人民提供强大而简单的工具以协助管理自己的资源。
NTXshape
NTXShape将CARIS NTX格式转换到更广泛的ESRI shape文件格式。
Nunaliit
Nunaliit框架旨在使网际地图制造——讲述故事和探索空间、时间、知识、感觉的关系——变得简单。初步发展的重点放在用以组织和连接内容使其有意义的XML架构,以及一个将这些信息渲染成互动网络界面的编译器。这个系统在XML大行其道的今天非常有用。
OGCConnector
OGC连接器是一个开源ArcIMS服务连接,由位于密苏里州罗拉的美国地质调查局中部大陆测绘中心开发。OGCConnector工具支持OGC渲层描述符(SLD)格式,正确掌握重投影需求,由于它可以连接ArcIMS服务连接器,维护相同的证明需要ArcIMS Servlet认证。
OGDI
OGDI是开放地理数据商店界面。OGDI是一个应用程序接口(API),使用一个标准的连接方法,与GIS软件包(应用)和不同的地空间数据产品联合工作。OGDI通过任何TCP/IP网络构建便于散播的客户端/服务器架构,和易于接近几种地理空间数据产品/格式的驱动导向驱动。
OGLE
OGLE(即OpenGLExtractor)是一个Eyebeam R&D软件包,允许捕捉和重用来自微软视窗三维应用的三维地理数据。
OGR
OGR简单特征库是一个C++开源库(及命令行工具),支持读(有时也可以写)不同矢量文件格式包括ESRI shapefiles,和MapInfo mid/mif、TAB格式。
OneMap
Project:OneMap是一个长期项目,促进融合标准网络技术和地理内容,时常被称为GeoWeb。进行尖端研发,并以网络服务部署结果。
Open
3D GIS:开发三维地理信息系统是一个开源项目,主要目标是提供简单的方法来从网络地理数据库显示三维物体。
Open
CASCADE:Open CASCADE是一个强大的三维建模内核。它包括了可重用的开源C++对象库。Open CASCADE被用于创建任何形式的指定范围三维图形应用,包括计算机辅助设计、计算机辅助工程、计算机辅助制造、建筑工程建造、地理信息系统、逆向工程、计量、光学仿真、拓扑等。
OpenDMTP
开放设备监视和跟踪协议,或说OpenDMTP,是一种协议和框架,允许服务器和设备(客户端)间通过互联网和类似网络进行双向数据传输。OpenDMTP特别针对基于位置的信息(LBS)如GPS、温度和其他数据的远距离监视设备。OpenDMTP不大,特别适于微设备,如PDA、移动电话、定制OEM设备。
OpenDX
IBM的开放可视化数据浏览器是一个可视化的框架,给予用户为他们的数据添加高阶可视化和分析技术的能力。这些技术可以被用来协助用户在广阔的领域,包括科学、工程、医药和商业,取得新的透视数据。
OpenEV
OpenEV是一个库,为查看和分析栅格和矢量数据的应用所引用。
OpenLayers
OpenMap
“BBN技术”的OpenMap包基于JavaBeans程序工具包。使用OpenMap,可以快速建立应用和小程序从遗产数据库和应用获取数据。OpenMap提供方法允许用户观看和处理地理空间信息。
OpenSVGMapserver:一个开源的在网上出版arcview shapefiles解决方案,基于HTML、SVG、JavaScript、PHP和MySQL数据库,支持互动和过滤。2003年后代码不再更新。
osgPlanet
osgPlanet是一个在OpenSceneGraph、libwms、OSSIM之上建立的三维地理空间查看器。灵感来自BlueMarbleViewer,osgPlanet扩展空间查看,在网络上获得本地地理格式、高程数据集,和OGC的网络地图服务(WMS)接口。osgPlanet是一个C++库,包含了作为示范的osgplanetviewer。
OSSIM
OSRS(开源遥感)的OSSIM(开源软件影像图)项目。读作“awesome”,OSSIM项目利用现有的开源算法、工具和包建立一个遥感、图像处理和地理信息系统(GIS)分析综合数据库。
Paradise
天堂项目的目标是设计、实施和评价一个可扩展的、平行的地理信息系统,能够储存和处理大量数据集。
PerlDL
PDL(Perl数据语言)为标准的Perl提供紧密存储和迅速操纵大型N维数据数组的能力,这种能力是计算科学中的面包和奶油。
PgArc
开发、测试和实施ESRI的ArcMap(ArcView/ArcInfo 8.x的组件)的开源解决方案。允许其与来自开源的PostGIS空间数据库(PostgreSQL的一个扩展)的数据实现互操作。
Phone Hack
有手机的好处之一是有一个接口连到你所连接的信号塔。由此信息,很容易得到“我到过哪里”类型的接口。
phpGIS
php GIS是一个用于所有GIS开发者的封装的信息/GIS系统。
Piccolo
Piccolo是一个革命性的方法,用Java创建鲁棒性的、全功能的图形程序,引人注目的功能如缩放和多重代表。Piccolo是一个基于Java2D API的扩展工具包。
PilotGaea GIS
为一套结合Web 3D导览、GIS、开发工具三合一的GIS产品,本身为GIS开发工具,具备高度整合与开发的弹性,以期符合不同领域的需求。PilotGaea Universe不但保留原来2D上的所有GIS属性与分析,在3D上,这些功能与运算更加广大。
PloneMap
一个基于MapServer的Plone图形应用。它允许在Plone站点内创建交互地图。网络访问者可以巡航地图而共同浏览或编辑地理位置数据。PloneMap在Plone内容管理系统上增加了地理代表。
p.mapper:p.mapper框架旨在提供多种功能和多种配置,以方便安装一个基于PHP/MapScript的MapServer应用。
Portfolio Explorer Open Source
探索者是由SRC——一个地理事物智能软件的开发者建立的一个数据和国家独立的地理编码。探索者分配经纬度坐标到每个美国的街道和路口。开发者可以载入数字地址编码向导,以及在LGPL协议下使用、开发探索者软件库。
POPulation MAPper
POPulation MAPper(友称popmap)是一个创造人口图的实用工具。Popmap可以从一个配置文件读取不同站点和每个站点的特定种类的人口权重。然后popmap可以为站点集从mapblast检索最佳图,根据人口密度给定的站点坐标画点。
PostGIS
Practical Map Server (PMS):PMS将地理内容带给了网页浏览器和其它适配客户端。
Predator
PREDATOR是一个对象关系型数据库系统。目标是建立一个研究和教育工具,可以处理现实生活中的数据库问题。在康奈尔大学,我们的研究重点一直是有效支持复杂数据类型(因此名为Predator Enhanced Data Type Object-Relational DBMS)的技术。
PrimaGIS
PrimaGIS最初启迪于Makina Corpus的PlongMap产品并借鉴了其中很多思想。PrimaGIS基于Mapserver,Python制图库(PCL)和Zope制图对象(ZCO)。
PROJ.4
PROj.4制图投影库被用于一些开源GIS项目包括GRASS、MapServer,以及OGDI。
PyDL
PyDL是一个IDL(RSI出品)的Linux自由克隆体。以Python开发,用到了Numerical Python、Python图像库和Dislin(策划)封装。执行阵列算法、24或8位图像和一些数字例程。
Pygps特点:记录轨迹、记录笔记、显示卫星、显示您的方位、在地图上显示您,在任何支持Python的机器上运行,libglade,从terraserver空中下载地图。
PyIMS
模仿ArcIMS4的Python地图脚本应用。启迪于refraction.net的Perl IMS模拟器。
PyOGCLib
PyOGCLib旨在制定和分发一个基于Python的OpenGIS规范实施库,特别是网络地图服务器(WMS)和网络功能服务器(WFS)。
Python Cartographic Library:Python制图库,或PCL,是一个从不同后端向地图渲染GIS数据的模块的封装。其任务在于成为开源GIS软件,如PROJ.4、GEOS、GDAL、OGR,以及MapServer的最佳Python接口,并易于为Python网页应用框架乃至其他可视化工具如matplotlib所用。
QCad
Quantum GIS
##QSlim
这个封装包括了两个部分,MixKit库和SlimKit表面模型工具集。
QuickWMS
JavaScript类,用于创建网页地图客户端和WMS服务器端口,遵守OpenGIS网页地图规范(0.7至1.1版本)。项目目标是能够使用用快速创建网页地图客户端。目标浏览器是Windows、Mac和Linux的Internet Explorer(5.5及以上版本)和Netscape(7.00及以上版本)。
R - Z
R语言
Rgeo
网页集,有意成为一个用R以及其他相关软件分析空间数据的资源指南。
RGIS
RGIS用于亨特学院的地理应用程序课,示范面向对象编程和地理信息科学理论。RGIS运行在无处不在的安装Java的工作站(Win95/98/NT、UNIX、Apple)。RGIS允许地理信息系统栅格数据由Arc/Info和ArcView导入和导出。
rmap:这个封装派生自在地球上进行正确经纬定位的个人地图系统需要。与CIA第二数据银行包含39轨磁带的COBAL数据建立了关联,它们运行在陈旧的主框架,也还有像样的地球矢量数据,也可以在公共域运行。
RoadMatcher
Vivid Solutions公司的RoadMatcher应用是一个有力的线性路网酏接工具。RoadMatcher提供了完整的可视环境以自动或人工匹配路网。
Roadster
Roadster旨在成为易用开源的制图软件。
SAGA GIS
SAGA可以视为地理信息系统,外加一个特别的地理数据处理的应用程序接口(API)。这个API简化了新算法执行,免除了开发者庞大编程支出,如用户界面设计和文件输入输出。SAGA API支持格网数据,如数字地形模型和卫星图片、矢量数据和表格。
SAMT:商业GIS非常昂贵而自由GIS(GRASS)不易使用。我们需要一个具备几个GIS功能的模型系统,如空间分析、一些空间技术和一个简单的GIS导入导出功能。SAMT的主要目标是包括不同模型(特别是模糊模型)的一个开源系统。
sdts2dem
Sol Katz开发的一份修订的sdts2dem实用工具。
Shapelib
Shapelib是一个简单的C API用于读写ArcView Shapefiles。代码形式发布,没有版权限制。
SharpMap
SharpMap是一个易用的地图渲染,可以渲染GIS数据,用于网页和桌面应用。引擎以C#书写,基于.NET 2.0框架。
SharpShape
ShapeLib.dll[4]中wrapper类的C#源代码:一个shape文件(shp、shx和dbf)读写库。
Shore
Shore项目的目标是设计、实施和评价一个持久化对象系统,服务于各种各样的目标应用,包括软硬件CAD系统、持续性编程语言、地理信息系统、卫星数据仓库和多媒体应用。
SHPTRANS
SHPTRANS是高精度、超高性能的NTv2数据变换和投影实用工具,读写shape文件。
Simple Map Server
生产地理图片的简单地图服务器。符合OpenGIS1.0.0和1.1.1规范。
Simple Map Client
简单地图客户端是允许浏览OpenGIS WMS服务器的Java应用。
SPECPR
SPECPR是一个互动的一维阵列处理系统,是反射光谱分析所需工具。它还有做其他工作和分析x,y配对数据的工具。
Spherekit
Spherekit是一个综合性空间插值和比较空间插值算法工具包。它基于UNIX,包括了完整的图形用户界面。使用通用绘图工具(GMT)显示插值域。
Splat
SPLAT!是一个射频信号传播、损失和地形分析工具,用于20MHz至20GHz频段。
Spring
SPRING是一个先进的GIS和遥感的图像处理系统,有一个面向对象数据模型,在单一环境提供栅格、矢量数据代表。
卫星软件计划:卫星软件计划(SSI)是一个非商业项目,其目标是推出高品质的免费开源软件,捕获、解码和显示气象卫星图像。
STARS
时空分析区域系统(STARS)是一个开源包,设计用于分析基于时间标准的空间数据。STARS汇集了一些最近开发的时空分析方法而为一个用户友好图形环境,提供一系列的动态链接图形视角。
sunclock
Sunlock是一个X11应用程序,显示地球地图,包括照明部分,绘制黑暗区域。除了为默认区域提供本地时间,它还显示主要城市的GMT时间、法律和太阳时间、经度和纬度,以及地球任意位置相互之间的距离。
SuperGIS
台湾崧旭资讯股份有限公司所开发的GIS软件产品套件的总称。
SVG Viewer
CSIRO SVG工具包是一个对延展矢量图形(SVG)做不同事情的实用工具的集合。
TARDEM
一套统计数字高程数据的程序。
Terraform
Terraform是一个开源的互动高程模型生产分析程序,可以生产随机数据和转换。
TerraLib
TerraLib是一个GIS类和函数库,使用对象联系型数据库进行GIS应用开发。TerraLib旨在为GIS开发者提供一个大的数据集架构和算法。
TGR2KML
这个程序转换TIGER多边形而为KML格式。支持的TIGER版本早打TIGER94晚至TIGER 2006第二版。
TGR2SHP
TGR2SHP 7.01将所有TIGER层(点、线、多边形)转换至ESRI格式shape文件。
TGR2MIF
转换TIGER而至MapInfo MIF/MID格式文件。概要文件抽取(SF1toTable、SF2toTable等)用于从Census2000文件抽取图层。
Thgis
这是一个共享软件,由tuhang创建并支持,提供客户端与服务器的能力以在线再现虚拟地球及其他GIS的功能。
Thuban
Thuban是一个互动的地理数据阅览器,具有以下特点:1)导航缩放,2)通过对象选择、对象记录选择查明属性,3)层管理层类型:线=多边形=点=地理图片,4)说明编辑器可视化外表控制,5)表管理查询和加入表,6)打印和输出供远期处理。
tkgeomap
Tkgeomap是一组Tcl/Tk扩展,供显示和互操作地理数据。
TMRS
老虎制图和路径服务器(TMRS)被写来促进建立开源GPS导航软件。它的目标是简化街一级路由和为开发用户友好界面的地图绘制功能要素。数据来自美国人口普查,被称为“老虎”。
TOPAZ
TOPAZ(地形参数)是一个自动数字景观分析工具,用于地形评估、排水鉴定、分水岭分割和下抓参数。虽然TOPAZ设计的主要目的是协助地形评价和分水岭参数化以支持水利模型分析,它也有应用于不同的地貌、环境和遥感应用。
Triangle
Triangle产生确切的Delaunay三角网、约束Delaunay三角网、控制Delaunay三角网的质量。后者可由不小的角度产生,因此适于有限元分析。
uDig
uDig是一个开源空间数据查看器/编辑器,对OpenGIS标准,关于互联网GIS、网络地图服务器和网络功能服务器有特别的加强。uig将提供一个一般的java平台来用开源组件建设空间应用。
vec2web
vec2web是一个小工具将矢量绘图(现有DXF)转换为网络可用的图形(现有PNG)。
VGMap
VGMap是Eyebeam R&D创建的一个新的库,允许设计者、开发者和绘图爱好者在谷歌地图上用比标准系统更丰富的手段叠置图层。它被称做VGMap,因为它为令人艳羡的GMap API添加了矢量绘图能力。
vhclmaps
vhclmaps(原ivmaps和vhclserv)是一个地图阅览和空间数据服务的封装,与美国地质调查局所属那样的地图数据库协作。
View Dog
ViewDog是一个查看器,用于nurbs功能,多边形几何,一定的三维域功能表面(通过匹配管支持)。
Vis5d
Vis5d+是一个测定体积的科学数据三维可视化程序,增添了特性如OpenGL平滑接口渲染、Tcl脚本、地理数据地图投影和动画。
Virtual Terrain Project (VTP)
VTP的目标是轻松构建互动真实世界的每一部分,三维数字化形式。这一目标将需要计算机辅助设计、地理信息系统、视觉模拟、测量和遥感领域的协同一致。VTP在现场施工、特征提取和渲染算法等方面收集信息和追踪进展。
Visual Basic GIS
用Visual Basic.NET写的GIS工具。
WAILI Wavelets Library
WAILI是一个小波变换库。它包括一些基于小波的基本图像处理任务进而形成更复杂的图像处理任务之中坚。
wayp2shp:Wayp2shp是一个简单的C程序可以读取Waypoint+文件并转换为shape文件。
WinDisp
Windisp是一个公共域,易于使用的软件包来显示和分析卫星图像、地图和相关数据库,重点是粮食安全预警。WinDisp最初是粮农组织全球信息和预警系统。
worldKit
worldKit是一个易用和灵活的网络绘图应用。轻量级GIS。它是一个基于SWF的应用,用XML控制,RSS作种。独立使用或集成进更大项目。
Xastir
Xastir是用于接受和绘出ARPS(tm)位置包的项目。由世界各地的程序员协作开发。Xastir支持许多地图格式并高度可定制。
XCSoar:XCSoar是一个Pocket PC操作系统上的战术滑行电脑。它能在远达WM2003SE的老旧硬件(PPC平台)运行。设备到位时也将支持WM2005(工作已经开始)。
Xearth:Windows的Xearth是Kirk Johnson的原始xearth项目在微软视窗的移植。Xearth在用户桌面上渲染地球的阴影图像,如同从所喜爱的太空制高点俯视。
Xplanet
Xplanet启发自Xearth,在X根窗口渲染地球图像。方位、墨卡托、Mollweide、正射或矩形投影的地球在一个窗口被显示于出来,用户使用OpenGL或Mesa进行交互。另一星球和一些卫星也会被显示。
XV:xv是一个X Window系统的交互图像处理程序。
Yg:Ygl在X11下模拟SGI的GL例程。出于两个原因被书写:1)在RS/6000 GT4硬件,Ygl两倍速(circf())于GL(奇怪,真的吗?);2)在非GL硬件乃至远端X服务器运行二维图形。
Zipdy
Zipdy是一个计算两邮编之间距离和在RDBMS所有邮编记录中查找x英里以外的另一邮编。
Zodius Zodius
是快速的地面建起矢量图形库。它试图执行Flash和SVG格式路径作图,结合最快速度和最优质量。
JSON和JSONB
PostgreSQL不仅是关系型数据库,同时支持丰富的NoSQL特性
本文主要包含以下三部分内容:
- PostgreSQL的 JSON和JSONB数据类型简介
- JSON与JSONB读写性能测试
- PostgreSQL全文检索支持JSON和JSONB(PosgreSQL 10 新特性)
PostgreSQL的JSON和JSONB数据类型
PostgreSQL支持非关系数据类型json (JavaScript Object Notation),本节介绍json类型、json与jsonb差异、json与jsonb操作符和函数,以及jsonb键值的追加、删除、更新。
JSON类型简介
PotgreSQL早在9.2版本已经提供了json类型,并且随着大版本的演进,PostgreSQL对json的支持趋于完善,例如提供更多的json函数和操作符方便应用开发,一个简单的json类型例子如下:
mydb=> SELECT '{"a":1,"b":2}'::json;
json
---------------
{"a":1,"b":2}
为了更好演示json类型,接下来创建一张表,如下所示:
mydb=> CREATE TABLE test_json1 (id serial primary key,name json);
CREATE TABLE
以上示例定义字段name为json类型,插入表数据,如下所示:
mydb=> INSERT INTO test_json1 (name)
VALUES ('{"col1":1,"col2":"francs","col3":"male"}');
INSERT 0 1
mydb=> INSERT INTO test_json1 (name)
VALUES ('{"col1":2,"col2":"fp","col3":"female"}');
INSERT 0 1
查询表test_json1
数据:
mydb=> SELECT * FROM test_json1;
id | name
----+------------------------------------------
1 | {"col1":1,"col2":"francs","col3":"male"}
2 | {"col1":2,"col2":"fp","col3":"female"}
查询JSON数据
通过->
操作符可以查询json数据的键值,如下所示:
mydb=> SELECT name -> 'col2' FROM test_json1 WHERE id=1;
?column?
----------
"francs"
(1 row)
如果想以文本格式返回json字段键值可以使用->>
符,如下所示:
mydb=> SELECT name ->> 'col2' FROM test_json1 WHERE id=1;
?column?
----------
francs
(1 row)
JSONB与JSON差异
PostgreSQL支持两种JSON数据类型:json和jsonb,两种类型在使用上几乎完全相同,两者主要区别为以下:json存储格式为文本而jsonb存储格式为二进制 ,由于存储格式的不同使得两种json数据类型的处理效率不一样,json类型以文本存储并且存储的内容和输入数据一样,当检索json数据时必须重新解析,而jsonb以二进制形式存储已解析好的数据,当检索jsonb数据时不需要重新解析,因此json写入比jsonb快,但检索比jsonb慢,后面会通过测试验证两者读写性能差异。
除了上述介绍的区别之外,json与jsonb在使用过程中还存在差异,例如jsonb输出的键的顺序和输入不一样,如下所示:
mydb=> SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
jsonb
--------------------------------------------------
{"bar": "baz", "active": false, "balance": 7.77}
(1 row)
而json的输出键的顺序和输入完全一样,如下所示:
mydb=> SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
json
-------------------------------------------------
{"bar": "baz", "balance": 7.77, "active":false}
(1 row)
另外,jsonb类型会去掉输入数据中键值的空格,如下所示:
mydb=> SELECT ' {"id":1, "name":"francs"}'::jsonb;
jsonb
-----------------------------
{"id": 1, "name": "francs"}
(1 row)
上例中id键与name键输入时是有空格的,输出显示空格键被删除,而json的输出和输入一样,不会删掉空格键:
mydb=> SELECT ' {"id":1, "name":"francs"}'::json;
json
-------------------------------
{"id":1, "name":"francs"}
(1 row)
另外,jsonb会删除重复的键,仅保留最后一个,如下所示:
mydb=> SELECT ' {"id":1,
"name":"francs",
"remark":"a good guy!",
"name":"test"
}'::jsonb;
jsonb
----------------------------------------------------
{"id": 1, "name": "test", "remark": "a good guy!"}
(1 row)
上面name键重复,仅保留最后一个name键的值,而json数据类型会保留重复的键值。 相比json大多数应用场景建议使用jsonb,除非有特殊的需求,比如对json的键顺序有特殊的要求。
JSONB与JSON操作符
PostgreSQL支持丰富的JSONB和JSON的操作符,举例如下: 以文本格式返回json类型的字段键值可以使用->>符,如下所示:
mydb=> SELECT name ->> 'col2' FROM test_json1 WHERE id=1;
?column?
----------
francs
(1 row)
字符串是否作为顶层键值,如下所示:
mydb=> SELECT '{"a":1, "b":2}'::jsonb ? 'a';
?column?
----------
t
(1 row)
删除json数据的键/值,如下所示:
mydb=> SELECT '{"a":1, "b":2}'::jsonb - 'a';
?column?
----------
{"b": 2}
(1 row)
JSONB与JSON函数
json与jsonb相关的函数非常丰富,举例如下: 扩展最外层的json对象成为一组键/值结果集,如下所示:
mydb=> SELECT * FROM json_each('{"a":"foo", "b":"bar"}');
key | value
-----+-------
a | "foo"
b | "bar"
(2 rows)
以文本形式返回结果,如下所示:
mydb=> SELECT * FROM json_each_text('{"a":"foo", "b":"bar"}');
key | value
-----+-------
a | foo
b | bar
(2 rows)
一个非常重要的函数为row_to_json()
函数,能够将行作为json对象返回,此函数常用来生成json测试数据,比如将一个普通表转换成json类型表:
mydb=> SELECT * FROM test_copy WHERE id=1;
id | name
----+------
1 | a
(1 row)
mydb=> SELECT row_to_json(test_copy) FROM test_copy WHERE id=1;
row_to_json
---------------------
{"id":1,"name":"a"}
(1 row)
返回最外层的json对像中的键的集合,如下所示:
mydb=> SELECT * FROM json_object_keys('{"a":"foo", "b":"bar"}');
json_object_keys
------------------
a
b
(2 rows)
jsonb键/值的追加、删除、更新
jsonb键/值追加可通过||操作符,如下增加sex键/值:
mydb=> SELECT '{"name":"francs","age":"31"}'::jsonb ||
'{"sex":"male"}'::jsonb;
?column?
------------------------------------------------
{"age": "31", "sex": "male", "name": "francs"}
(1 row)
jsonb键/值的删除有两种方法,一种是通过操作符号-删除,另一种通过操作符#-删除指定键/值。
通过操作符号-删除键/值如下:
mydb=> SELECT '{"name": "James", "email": "james@localhost"}'::jsonb
- 'email';
?column?
-------------------
{"name": "James"}
(1 row)
mydb=> SELECT '["red","green","blue"]'::jsonb - 0;
?column?
-------------------
["green", "blue"]
第二种方法是通过操作符#-删除指定键/值,通常用于有嵌套json数据删除的场景,如下删除嵌套contact中的fax键/值:
mydb=> SELECT '{"name": "James", "contact": {"phone": "01234 567890", "fax": "01987 543210"}}'::jsonb #- '{contact,fax}'::text[];
?column?
---------------------------------------------------------
{"name": "James", "contact": {"phone": "01234 567890"}}
(1 row)
删除嵌套aliases中的位置为1的键/值,如下所示:
mydb=> SELECT '{"name": "James", "aliases": ["Jamie","The Jamester","J Man"]}'::jsonb #- '{aliases,1}'::text[];
?column?
--------------------------------------------------
{"name": "James", "aliases": ["Jamie", "J Man"]}
(1 row)
键/值的更新也有两种方式,第一种方式为||操作符,||操作符可以连接json键,也可覆盖重复的键值,如下修改age键的值:
mydb=> SELECT '{"name":"francs","age":"31"}'::jsonb ||
'{"age":"32"}'::jsonb;
?column?
---------------------------------
{"age": "32", "name": "francs"}
(1 row)
第二种方式是通过jsonb_set
函数,语法如下:
jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean])
target指源jsonb数据,path指路径,new_value
指更新后的键值,create_missing
值为 true表示如果键不存在则添加,create_missing
值为 false表示如果键不存在则不添加,示例如下:
mydb=> SELECT jsonb_set('{"name":"francs","age":"31"}'::jsonb,'{age}','"32"'::jsonb,false);
jsonb_set
---------------------------------
{"age": "32", "name": "francs"}
(1 row)
mydb=> SELECT jsonb_set('{"name":"francs","age":"31"}'::jsonb,'{sex}','"male"'::jsonb,true);
jsonb_set
------------------------------------------------
{"age": "31", "sex": "male", "name": "francs"}
(1 row)
给JSONB类型创建索引
这一小节介绍给jsonb数据类型创建索引,jsonb数据类型支持GIN索引,为了便于说明,假如一个json字段内容如下,并且以jsonb格式存储。
{
"id": 1,
"user_id": 1440933,
"user_name": "1_francs",
"create_time": "2017-08-03 16:22:05.528432+08"
}
假如存储以上jsonb数据的字段名为user_info
,表名为tbl_user_jsonb
,在user_info
字段上创建GIN索引语法如下:
CREATE INDEX idx_gin ON tbl_user_jsonb USING gin(user_info);
jsonb上的GIN索引支持@>
、?
、 ?&
、?|
操作符,例如以下查询将会使用索引。
SELECT * FROM tbl_user_jsonb WHERE user_info @> '{"user_name": "1_frans"}'
但是以下基于jsonb键值的查询不会走索引idx_gin
,如下所示:
SELECT * FROM tbl_user_jsonb WHERE user_info->>'user_name'= '1_francs';
如果要想提升基于jsonb类型的键值检索效率,可以在jsonb数据类型对应的键值上创建索引,如下所示:
CREATE INDEX idx_gin_user_infob_user_name ON tbl_user_jsonb USING btree
((user_info ->> 'user_name'));
创建以上索引后,上述根据user_info->>'user_name'
键值查询的SQL将会走索引。
JSON与JSONB读写性能测试
上一小节介绍了jsonb数据类型索引创建相关内容,本小节将对json、jsonb读写性能进行简单对比,在第3章数据类型章节中介绍json、jsonb数据类型时提到了两者读写性能的差异,主要表现为json写入时比jsonb快,但检索时比jsonb慢,主要原因为:json存储格式为文本而jsonb存储格式为二进制,存储格式的不同使得两种json数据类型的处理效率不一样,json类型存储的内容和输入数据一样,当检索json数据时必须重新解析,而jsonb以二进制形式存储已解析好的数据,当检索jsonb数据时不需要重新解析。
构建JSON、JSONB测试表
下面通过一个简单的例子测试下json、jsonb的读写性能差异,计划创建以下三张表:
user_ini
:基础数据表,并插入200万测试数据;tbl_user_json
:: json 数据类型表,200万数据;tbl_user_jsonb
: jsonb 数据类型表,200万数据;
首先创建user_ini
表并插入200万测试数据,如下:
mydb=> CREATE TABLE user_ini(id int4 ,user_id int8, user_name character
varying(64),create_time timestamp(6) with time zone default
clock_timestamp());
CREATE TABLE
mydb=> INSERT INTO user_ini(id,user_id,user_name)
SELECT r,round(random()*2000000), r || '_francs'
FROM generate_series(1,2000000) as r;
INSERT 0 2000000
计划使用user_ini
表数据生成json、jsonb数据,创建user_ini_json
、user_ini_jsonb
表,如下所示:
mydb=> CREATE TABLE tbl_user_json(id serial, user_info json);
CREATE TABLE
mydb=> CREATE TABLE tbl_user_jsonb(id serial, user_info jsonb);
CREATE TABLE
JSON与JSONB表写性能测试
根据user_ini
数据通过row_to_json
函数向表user_ini_json
插入200万json数据,如下:
mydb=> \timing
Timing is on.
mydb=> INSERT INTO tbl_user_json(user_info) SELECT row_to_json(user_ini)
FROM user_ini;
INSERT 0 2000000
Time: 13825.974 ms (00:13.826)
从以上结果看出tbl_user_json
插入200万数据花了13秒左右;接着根据user_ini
表数据生成200万jsonb数据并插入表tbl_user_jsonb
,如下:
mydb=> INSERT INTO tbl_user_jsonb(user_info)
SELECT row_to_json(user_ini)::jsonb FROM user_ini;
INSERT 0 2000000
Time: 20756.993 ms (00:20.757)
从以上看出tbl_user_jsonb
表插入200万jsonb数据花了20秒左右,正好验证了json数据写入比jsonb快,比较两表占用空间大小,如下所示:
mydb=> \dt+ tbl_user_json
List of relations
Schema | Name | Type | Owner | Size | Description
--------+---------------+-------+--------+--------+-------------
pguser | tbl_user_json | table | pguser | 281 MB |
(1 row)
mydb=> \dt+ tbl_user_jsonb
List of relations
Schema | Name | Type | Owner | Size | Description
--------+----------------+-------+--------+--------+-------------
pguser | tbl_user_jsonb | table | pguser | 333 MB |
(1 row)
从占用空间来看,同样的数据量jsonb数据类型占用空间比json稍大。
查询tbl_user_json
表的一条测试数据,如下::
mydb=> SELECT * FROM tbl_user_json LIMIT 1;
id | user_info
---------+------------------------------------------------------------------------------------
2000001 | {"id":1,"user_id":1182883,"user_name":"1_francs","create_time":"2017-08-03T20:59:27.42741+08:00"}
(1 row)
JSON与JSONB表读性能测试
对于json、jsonb读性能测试我们选择基于json、jsonb键值查询的场景,例如,根据user_info
字段的user_name
键的值查询,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM tbl_user_jsonb WHERE user_info->>'user_name'='1_francs';
QUERY PLAN
-------------------------------------------------------------------------------------
Seq Scan on tbl_user_jsonb (cost=0.00..72859.90 rows=10042 width=143) (actual time=0.023..524.843 rows=1 loops=1)
Filter: ((user_info ->> 'user_name'::text) = '1_francs'::text)
Rows Removed by Filter: 1999999
Planning time: 0.091 ms
Execution time: 524.876 ms
(5 rows)
上述SQL执行时间为524毫秒左右,基于user_info
字段的user_name
键值创建btree索引如下:
mydb=> CREATE INDEX idx_jsonb ON tbl_user_jsonb USING btree
((user_info->>'user_name'));
再次执行上述查询,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM tbl_user_jsonb WHERE user_info->>'user_name'='1_francs';
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on tbl_user_jsonb (cost=155.93..14113.93 rows=10000 width=143) (actual time=0.027..0.027 rows=1 loops=1)
Recheck Cond: ((user_info ->> 'user_name'::text) = '1_francs'::text)
Heap Blocks: exact=1
-> Bitmap Index Scan on idx_jsonb (cost=0.00..153.43 rows=10000 width=0) (actual time=0.021..0.021 rows=1 loops=1)
Index Cond: ((user_info ->> 'user_name'::text) = '1_francs'::text)
Planning time: 0.091 ms
Execution time: 0.060 ms
(7 rows)
根据上述执行计划看出走了索引,并且SQL时间下降到0.060ms。为更好的对比tbl_user_json
、tbl_user_jsonb
表基于键值查询的效率,计划根据user_info
字段id键进行范围扫描对比性能,创建索引如下:
mydb=> CREATE INDEX idx_gin_user_info_id ON tbl_user_json USING btree
(((user_info ->> 'id')::integer));
CREATE INDEX
mydb=> CREATE INDEX idx_gin_user_infob_id ON tbl_user_jsonb USING btree
(((user_info ->> 'id')::integer));
CREATE INDEX
索引创建后,查询tbl_user_json表如下:
mydb=> EXPLAIN ANALYZE SELECT id,user_info->'id',user_info->'user_name'
FROM tbl_user_json
WHERE (user_info->>'id')::int4>1 AND (user_info->>'id')::int4<10000;
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on tbl_user_json (cost=166.30..14178.17 rows=10329 width=68) (actual time=1.167..26.534 rows=9998 loops=1)
Recheck Cond: ((((user_info ->> 'id'::text))::integer > 1) AND (((user_info ->> 'id'::text))::integer < 10000))
Heap Blocks: exact=338
-> Bitmap Index Scan on idx_gin_user_info_id (cost=0.00..163.72 rows=10329 width=0) (actual time=1.110..1.110 rows=19996 loops=
1)
Index Cond: ((((user_info ->> 'id'::text))::integer > 1) AND (((user_info ->> 'id'::text))::integer < 10000))
Planning time: 0.094 ms
Execution time: 27.092 ms
(7 rows)
根据以上看出,查询表tbl_user_json
的user_info
字段id键值在1到10000范围内的记录走了索引,并且执行时间为27.092毫秒,接着测试tbl_user_jsonb
表同样SQL的检索性能,如下所示:
mydb=> EXPLAIN ANALYZE SELECT id,user_info->'id',user_info->'user_name'
FROM tbl_user_jsonb
WHERE (user_info->>'id')::int4>1 AND (user_info->>'id')::int4<10000;
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on tbl_user_jsonb (cost=158.93..14316.93 rows=10000 width=68) (actual time=1.140..8.116 rows=9998 loops=1)
Recheck Cond: ((((user_info ->> 'id'::text))::integer > 1) AND (((user_info ->> 'id'::text))::integer < 10000))
Heap Blocks: exact=393
-> Bitmap Index Scan on idx_gin_user_infob_id (cost=0.00..156.43 rows=10000 width=0) (actual time=1.058..1.058 rows=18992 loops
=1)
Index Cond: ((((user_info ->> 'id'::text))::integer > 1) AND (((user_info ->> 'id'::text))::integer < 10000))
Planning time: 0.104 ms
Execution time: 8.656 ms
(7 rows)
根据以上看出,查询表tbl_user_jsonb
的user_info
字段id键值在1到10000范围内的记录走了索引并且执行时间为8.656毫秒,从这个测试看出jsonb检索比json效率高。
从以上两个测试看出,正好验证了“json写入比jsonb快,但检索时比jsonb慢”的观点,值得一提的是如果需要通过key/value进行检索,例如以下。
SELECT * FROM tbl_user_jsonb WHERE user_info @> '{"user_name": "2_francs"}';
这时执行计划为全表扫描,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM tbl_user_jsonb WHERE user_info @> '{"user_name": "2_francs"}';
QUERY PLAN
------------------------------------------------------------------------------------
Seq Scan on tbl_user_jsonb (cost=0.00..67733.00 rows=2000 width=143) (actual time=0.018..582.207 rows=1 loops=1)
Filter: (user_info @> '{"user_name": "2_francs"}'::jsonb)
Rows Removed by Filter: 1999999
Planning time: 0.065 ms
Execution time: 582.232 ms
(5 rows)
从以上看出执行时间为582毫秒左右,在tbl_user_jsonb
字段user_info
上创建gin索引,如下所示:
mydb=> CREATE INDEX idx_tbl_user_jsonb_user_Info ON tbl_user_jsonb USING gin
(user_Info);
CREATE INDEX
索引创建后,再次执行以下,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM tbl_user_jsonb WHERE user_info @> '{"user_name": "2_francs"}';
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on tbl_user_jsonb (cost=37.50..3554.34 rows=2000 width=143) (actual time=0.079..0.080 rows=1 loops=1)
Recheck Cond: (user_info @> '{"user_name": "2_francs"}'::jsonb)
Heap Blocks: exact=1
-> Bitmap Index Scan on idx_tbl_user_jsonb_user_info (cost=0.00..37.00 rows=2000 width=0) (actual time=0.069..0.069 rows=1 loop
s=1)
Index Cond: (user_info @> '{"user_name": "2_francs"}'::jsonb)
Planning time: 0.094 ms
Execution time: 0.114 ms
(7 rows)
从以上看出走了索引,并且执行时间下降到了0.114毫秒。
这一小节测试了json、jsonb数据类型读写性能差异,验证了json写入时比jsonb快,但检索时比jsonb慢的观点。
PostgreSQ全文检索支持JSON和JSONB
这一小节将介绍PostgreSQL10的一个新特性:全文检索支持json、jsonb数据类型,本小节分两部分,第一部分简单介绍PostgreSQL全文检索,第二部分演示全文检索对json、jsonb数据类型的支持。
PostgreSQL全文检索简介
对于大多数应用全文检索很少放到数据库中实现,一般使用单独的全文检索引擎,例如基于SQL全文检索引擎Sphinx。PostgreSQL支持全文检索,对于规模不大的应用如果不想搭建专门的搜索引擎,PostgreSQL的全文检索也可以满足需求。
如果没有使用专门的搜索引擎,大部检索需要通过数据库like操作匹配,这种检索方式主要缺点在于:
- 不能很好的支持索引,通常需全表扫描检索数据,数据量大时检索性能很低。
- 不提供检索结果排序,当输出结果数据量非常大时表现更加明显。
PostgreSQL全文检索能有效地解决这个问题,PostgreSQL全文检索通过以下两种数据类型来实现。
tsvector
tsvector全文检索数据类型代表一个被优化的可以基于搜索的文档,将一串字符串转换成tsvector全文检索数据类型,如下:
mydb=> SELECT 'Hello,cat,how are u? cat is smiling! '::tsvector;
tsvector
--------------------------------------------------
'Hello,cat,how' 'are' 'cat' 'is' 'smiling!' 'u?'
(1 row)
可以看到,字符串的内容被分隔成好几段,但通过::tsvector只是做类型转换,没有进行数据标准化处理,对于英文全文检索可通过函数to_tsvector
进行数据标准化,如下所示:
mydb=> SELECT to_tsvector('english','Hello cat,');
to_tsvector
-------------------
'cat':2 'hello':1
(1 row)
tsquery
tsquery表示一个文本查询,存储用于搜索的词,并且支持布尔操作&、|、!,将字符串转换成tsquery,如下所示:
mydb=> SELECT 'hello&cat'::tsquery;
tsquery
-----------------
'hello' & 'cat'
(1 row)
上述只是转换成tsquery类型,而并没有做标准化,使用to_tsquery
函数可以执行标准化,如下所示:
mydb=> SELECT to_tsquery( 'hello&cat' );
to_tsquery
-----------------
'hello' & 'cat'
(1 row)
一个全文检索示例如下,检索字符串是否包括hello和cat字符,本例中返回真。
mydb=> SELECT to_tsvector('english','Hello cat,how are u') @@
to_tsquery( 'hello&cat' );
?column?
----------
t
(1 row)
检索字符串是否包含字符hello和dog,本例中返回假。
mydb=> SELECT to_tsvector('english','Hello cat,how are u') @@
to_tsquery( 'hello&dog' );
?column?
----------
f
(1 row)
有兴趣的读者可以测试tsquery的其他操作符,例如|、!等。
注意:这里使用了带双参数的to_tsvector
函数,函数to_tsvector
双参数的格式如下:
to_tsvector([ config regconfig , ] document text),本节to_tsvector函数指定了config参数为english,如果不指定config参数,则默认使用default_text_search_config参数的配置。
英文全文检索例子
下面演示一个英文全文检索示例,创建一张测试表并插入200万测试数据,如下所示:
mydb=> CREATE TABLE test_search(id int4,name text);
CREATE TABLE
mydb=> INSERT INTO test_search(id,name) SELECT n, n||'_francs'
FROM generate_series(1,2000000) n;
INSERT 0 2000000
执行以下SQL,查询test_search
表name字段包含字符1_francs
的记录。
mydb=> SELECT * FROM test_search WHERE name LIKE '1_francs';
id | name
----+----------
1 | 1_francs
(1 row)
执行计划如下:
mydb=> EXPLAIN ANALYZE SELECT * FROM test_search WHERE name LIKE '1_francs';
QUERY PLAN
-------------------------------------------------------------------------------------Seq Scan on test_search (cost=0.00..38465.04 rows=204 width=18) (actual time=0.022..261.766 rows=1 loops=1)
Filter: (name ~~ '1_francs'::text)
Rows Removed by Filter: 1999999
Planning time: 0.101 ms
Execution time: 261.796 ms
(5 rows)
以上执行计划走了全表扫描,执行时间为261毫秒左右,性能很低,接着创建索引,如下所示:
mydb=> CREATE INDEX idx_gin_search ON test_search USING gin
(to_tsvector('english',name));
CREATE INDEX
执行以下SQL,查询test_search
表name字段包含字符1_francs
的记录。
mydb=> SELECT * FROM test_search WHERE to_tsvector('english',name) @@
to_tsquery('english','1_francs');
id | name
----+----------
1 | 1_francs
(1 row)
再次查看执行计划和执行时间,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM test_search WHERE to_tsvector('english',name) @@
to_tsquery('english','1_francs');
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on test_search (cost=18.39..128.38 rows=50 width=36) (actual time=0.071..0.071 rows=1 loops=1)
Recheck Cond: (to_tsvector('english'::regconfig, name) @@ '''1'' & ''franc'''::tsquery)
Heap Blocks: exact=1
-> Bitmap Index Scan on idx_gin_search (cost=0.00..18.38 rows=50 width=0) (actual time=0.064..0.064 rows=1 loops=1)
Index Cond: (to_tsvector('english'::regconfig, name) @@ '''1'' & ''franc'''::tsquery)
Planning time: 0.122 ms
Execution time: 0.104 ms
(7 rows)
创建索引后,以上查询走了索引并且执行时间下降到0.104毫秒,性能提升了3个数量级,值得一提的是如果SQL改成以下,则不走索引,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM test_search
WHERE to_tsvector(name) @@ to_tsquery('1_francs');
QUERY PLAN
-------------------------------------------------------------------------------------
Seq Scan on test_search (cost=0.00..1037730.00 rows=50 width=18) (actual time=0.036..10297.764 rows=1 loops=1)
Filter: (to_tsvector(name) @@ to_tsquery('1_francs'::text))
Rows Removed by Filter: 1999999
Planning time: 0.098 ms
Execution time: 10297.787 ms
(5 rows)
由于创建索引时使用的是to_tsvector('english',name)
函数索引,带了两个参数,因此where条件中的to_tsvector
函数带两个参数才能走索引,而to_tsvector(name)
不走索引。
JSON、JSONB全文检索实践
在PostgreSQL10版本之前全文检索不支持json和jsonb数据类型,10版本的一个重要特性是全文检索支持json和jsonb数据类型,这一小节演示下10版本的这个新特性。
PostgreSQL10版本与9.6版本to_tsvector
函数的差异
先来看下9.6版本to_tsvector
函数,如下:
[postgres@pghost1 ~]$ psql francs francs
psql (9.6.3)
Type "help" for help.
mydb=> \df *to_tsvector*
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+-------------------+------------------+---------------------+--------
pg_catalog | array_to_tsvector | tsvector | text[] | normal
pg_catalog | to_tsvector | tsvector | regconfig, text | normal
pg_catalog | to_tsvector | tsvector | text | normal
(3 rows)
从以上看出9.6版本to_tsvector
函数的输入参数仅支持text、text[]数据类型,接着看下10版本的to_tsvector
函数,如下所示:
[postgres@pghost1 ~]$ psql mydb pguser
psql (10.0)
Type "help" for help.
mydb=> \df *to_tsvector*
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+-------------------+------------------+---------------------+--------
pg_catalog | array_to_tsvector | tsvector | text[] | normal
pg_catalog | to_tsvector | tsvector | json | normal
pg_catalog | to_tsvector | tsvector | jsonb | normal
pg_catalog | to_tsvector | tsvector | regconfig, json | normal
pg_catalog | to_tsvector | tsvector | regconfig, jsonb | normal
pg_catalog | to_tsvector | tsvector | regconfig, text | normal
pg_catalog | to_tsvector | tsvector | text | normal
(7 rows)
从以上看出,10版本的to_tsvector
函数支持的数据类型增加了json和jsonb。
创建数据生成函数
为了便于生成测试数据,创建以下两个函数用来随机生成指定长度的字符串,创建random_range(int4, int4)
函数如下:
CREATE OR REPLACE FUNCTION random_range(int4, int4)
RETURNS int4
LANGUAGE SQL
AS $$
SELECT ($1 + FLOOR(($2 - $1 + 1) * random() ))::int4;
$$;
接着创建random_text_simple(length int4)
函数,此函数会调用random_range(int4, int4)
函数。
CREATE OR REPLACE FUNCTION random_text_simple(length int4)
RETURNS text
LANGUAGE PLPGSQL
AS $$
DECLARE
possible_chars text := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
output text := '';
i int4;
pos int4;
BEGIN
FOR i IN 1..length LOOP
pos := random_range(1, length(possible_chars));
output := output || substr(possible_chars, pos, 1);
END LOOP;
RETURN output;
END;
$$;
random_text_simple(length int4)
函数可以随机生成指定长度字符串,如下随机生成含三位字符的字符串。
mydb=> SELECT random_text_simple(3);
random_text_simple
--------------------
LL9
(1 row)
随机生成含六位字符的字符串,如下所示:
mydb=> SELECT random_text_simple(6);
random_text_simple
--------------------
B81BPW
(1 row)
后面会用到这个函数生成测试数据。
创建JSON测试表
创建user_ini
测试表,并通过random_text_simple(length int4)
函数插入100万随机生成六位字符的字符串测试数据,如下所示:
mydb=> CREATE TABLE user_ini(id int4 ,user_id int8,
user_name character varying(64),
create_time timestamp(6) with time zone default clock_timestamp());
CREATE TABLE
mydb=> INSERT INTO user_ini(id,user_id,user_name)
SELECT r,round(random()*1000000), random_text_simple(6)
FROM generate_series(1,1000000) as r;
INSERT 0 1000000
创建tbl_user_search_json
表,并通过row_to_json
函数将表user_ini
行数据转换成json数据,如下所示:
mydb=> CREATE TABLE tbl_user_search_json(id serial, user_info json);
CREATE TABLE
mydb=> INSERT INTO tbl_user_search_json(user_info)
SELECT row_to_json(user_ini) FROM user_ini;
INSERT 0 1000000
生成的数据如下:
mydb=> SELECT * FROM tbl_user_search_json LIMIT 1;
id | user_info
----+-----------------------------------------------------------------------------------------------
1 | {"id":1,"user_id":186536,"user_name":"KTU89H","create_time":"2017-08-05T15:59:25.359148+08:00"}
(1 row)
JSON数据全文检索测试
使用全文检索查询表tbl_user_search_json
的user_info
字段中包含KTU89H字符的记录,如下所示:
mydb=> SELECT * FROM tbl_user_search_json
WHERE to_tsvector('english',user_info) @@ to_tsquery('ENGLISH','KTU89H');
id | user_info
----+----------------------------------------------------------------------------------------
1 | {"id":1,"user_id":186536,"user_name":"KTU89H","create_time":"2017-08-05T15:59:25.359148+08:00"}
(1 row)
以上SQL能正常执行说明全文检索支持json数据类型,只是上述SQL走了全表扫描性能低,执行时间为8061毫秒,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM tbl_user_search_json
WHERE to_tsvector('english',user_info) @@ to_tsquery('ENGLISH','KTU89H');
QUERY PLAN
-----------------------------------------------------------------------------------
Seq Scan on tbl_user_search_json (cost=0.00..279513.00 rows=5000 width=104) (actual time=0.046..8061.858 rows=1 loops=1)
Filter: (to_tsvector('english'::regconfig, user_info) @@ '''ktu89h'''::tsquery)
Rows Removed by Filter: 999999
Planning time: 0.091 ms
Execution time: 8061.880 ms
(5 rows)
创建如下索引:
mydb=> CREATE INDEX idx_gin_search_json ON tbl_user_search_json USING
gin(to_tsvector('english',user_info));
CREATE INDEX
索引创建后,再次执行以下SQL,如下所示:
mydb=> EXPLAIN ANALYZE SELECT * FROM tbl_user_search_json WHERE to_tsvector('english',user_info) @@ to_tsquery('ENGLISH','KTU89H');
QUERY PLAN
-------------------------------------------------------------------------------------
Bitmap Heap Scan on tbl_user_search_json (cost=50.75..7876.06 rows=5000 width=104) (actual time=0.024..0.024 rows=1 loops=1)
Recheck Cond: (to_tsvector('english'::regconfig, user_info) @@ '''ktu89h'''::tsquery)
Heap Blocks: exact=1
-> Bitmap Index Scan on idx_gin_search_json (cost=0.00..49.50 rows=5000 width=0) (actual time=0.018..0.018 rows=1 loops=1)
Index Cond: (to_tsvector('english'::regconfig, user_info) @@ '''ktu89h'''::tsquery)
Planning time: 0.113 ms
Execution time: 0.057 ms
(7 rows)
从上述执行计划看出走了索引,并且执行时间降为0.057毫秒,性能非常不错。
函数
操作符
操作符 | 描述 | 示例 | 结果 |
= | 相等 | SELECT ARRAY[1.1,2.1,3.1]::int[] = ARRAY[1,2,3]; | t |
<> | 不等于 | select ARRAY[1,2,3] <> ARRAY[1,2,4]; | t |
< | 小于 | select ARRAY[1,2,3] < ARRAY[1,2,4]; | t |
> | 大于 | select ARRAY[1,4,3] > ARRAY[1,2,4]; | t |
<= | 小于或等于 | select ARRAY[1,2,3] <= ARRAY[1,2,3]; | t |
>= | 大于或等于 | select ARRAY[1,4,3] >= ARRAY[1,4,3]; | t |
@> | 包含 | select ARRAY[1,4,3] @> ARRAY[3,1]; | t |
<@ | 包含于 | select ARRAY[2,7] <@ ARRAY[1,7,4,2,6]; | t |
&& | 重叠(是否有相同元素) | select ARRAY[1,4,3] && ARRAY[2,1]; | t |
|| | 数组与数组连接 | select ARRAY[1,2,3] || ARRAY[4,5,6]; | {1,2,3,4,5,6} |
|| | 数组与数组连接 | select ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9]]; | {{1,2,3},{4,5,6},{7,8,9}} |
|| | 元素与数组连接 | select 3 || ARRAY[4,5,6]; | {3,4,5,6} |
|| | 数组与元素连接 | select ARRAY[4,5,6] || 7; | {4,5,6,7} |
函数
函数 | 返回类型 | 描述 | 示例 | 结果 |
| anyarray | 在数组末尾追加元素 | SELECT array_append(ARRAY[1,2], 3); | {1,2,3} |
| anyarray | 连接两个数组 | SELECT array_cat(ARRAY[1,2,3], ARRAY[4,5]); | {1,2,3,4,5} |
| int | 返回数组维数 | SELECT array_ndims(ARRAY[[1,2,3], [4,5,6]]); | 2 |
| text | 返回数组维数的文本表示 | SELECT array_dims(ARRAY[[1,2,3], [4,5,6]]); | [1:2][1:3] |
| anyarray | 使用提供的值和维度初始化一个数组,其中anyelement是值,第一个int[]是数组的长度,第二个int[]是数组下界,下界默认是1 | SELECT array_fill(7, ARRAY[3], ARRAY[2]); | [2:4]={7,7,7} |
| int | 返回数组指定维度的长度 | SELECT array_length(array[1,2,3], 1); | 3 |
| int | 返回数组指定维度的下界 | SELECT array_lower('[0:2]={1,2,3}'::int[], 1); | 0 |
| int | 返回数组元素anyelement从数组的[,int]位置(默认为1)开始第一次出现在数组中的位置,数组必须是一维的 | SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon'); | 2 |
| int[] | 返回元素在数组中的所有位置 | SELECT array_positions(ARRAY['A','A','B','A'], 'A'); | {1,2,4} |
| anyarray | 在数组开头添加新的元素 | SELECT array_prepend(1, ARRAY[2,3]); | {1,2,3} |
| anyarray | 从数组中删除所有的指定元素,必须是一维数组 | SELECT array_remove(ARRAY[1,2,3,2], 2); | {1,3} |
| anyarray | 替换指定数组元素为新的元素 | SELECT array_replace(ARRAY[1,2,5,4], 5, 3); | {1,2,3,4} |
| text | 将数组元素使用分隔符连接为文本,NULL可以使用指定元素替换 | SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*'); | 1,2,3,*,5 |
| int | 数组指定维度的上届 | SELECT array_upper(ARRAY[1,8,3,7], 1); | 4 |
| int | 返回数组所有维度的长度总和,如果是空数组则返回0 | SELECT cardinality(ARRAY[[1,2],[3,4]]); | 4 |
| text[] | 将文本使用分隔符分隔后转换为数组,如果指定第三个参数,则第三个参数在数组中被转换为NULL | SELECT string_to_array('xx~^~yy~^~zz', '~^~', 'yy'); | {xx,NULL,zz} |
| setof anyelement | 将数组元素转换为行 | SELECT unnest(ARRAY[1,2]); | 1 |
| setof anyelement, anyelement [, ...] | 将多维数组转换为行集合,其中第一个数组显示为第一列,第二个数组显示为第二列,以此类推。但是这个函数只在from子句中使用 | SELECT * from unnest(ARRAY[1,2],ARRAY['foo','bar','baz']); | unnest | unnest |
视图
MATERIALIZED VIEW
PG 9.3 版本之后开始支持物化视图。
View 视图:
虚拟,不存在实际的数据,在查询视图的时候其实是对视图内的表进行查询操作。
物化视图:
实际存在,将数据存成一张表,查询的时候对这个表进行操作。物化视图内的数据需要和表的数据进行同步,这就是refresh。
实验环境:
CentOS 7
PG 10.4
操作实验:
初始化环境:
创建表,并插入数据
mytest=# create table t1 (id int ,col1 varchar(10),col2 varchar(10));
mytest=# create table t2 (id int ,col3 varchar(10), col4 varchar(10), col5 varchar(10));
mytest=# insert into t1 values (1,'a','b'); ......
mytest=# insert into t2 values (1,'c','d','e'); ......
mytest=# select * from t1;
id | col1 | col2
----+------+------
1 | a | b
2 | a | b
3 | a | b
4 | a | b
5 | a | b
(5 rows)
mytest=# select * from t2;
id | col3 | col4 | col5
----+------+------+------
1 | c | d | e
2 | c | d | e
3 | c | d | e
4 | c | d | e
5 | c | d | e
(5 rows)
创建物化视图:
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_t1_t2 (t1_id,t2_id, col1,col2,col3,col4,col5)
AS
SELECT t1.id, t2.id, t1.col1,t1.col2,t2.col3,t2.col4,t2.col5 from t1,t2
where t1.id = t2.id
WITH DATA;
mytest=# select * from mv_t1_t2;
t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
1 | 1 | a | b | c | d | e
2 | 2 | a | b | c | d | e
3 | 3 | a | b | c | d | e
4 | 4 | a | b | c | d | e
5 | 5 | a | b | c | d | e
(5 rows)
刷新物化视图:
mytest=# insert into t1 values (11,'x','y');
mytest=# insert into t2 values (11,'x','y','z');
对表进行操作,不改变物化视图中的数据。查询物化视图,数据没有改变
mytest=# select * from mv_t1_t2 ;
t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
1 | 1 | a | b | c | d | e
2 | 2 | a | b | c | d | e
3 | 3 | a | b | c | d | e
4 | 4 | a | b | c | d | e
5 | 5 | a | b | c | d | e
(5 rows)
全量更新:
刷新物化视图才能使物化视图的数据改变。
mytest=# REFRESH MATERIALIZED VIEW mv_t1_t2 WITH DATA;
mytest=# SELECT * FROM mv_t1_t2 ;
t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
1 | 1 | a | b | c | d | e
2 | 2 | a | b | c | d | e
3 | 3 | a | b | c | d | e
4 | 4 | a | b | c | d | e
5 | 5 | a | b | c | d | e
11 | 11 | x | y | x | y | z
(6 rows)
增量更新
只有当物化视图中存在unique index的时候,refresh物化视图才能使用增量更新,加入concurrently参数。否则报错。
mytest=# REFRESH MATERIALIZED VIEW CONCURRENTLY mv_t1_t2 WITH DATA;
ERROR: cannot refresh materialized view "public.mv_t1_t2" concurrently
HINT: Create a unique index with no WHERE clause on one or more columns of the materialized view.
mytest=# create unique index uidx_mv_id on mv_t1_t2 (t1_id );
mytest=# REFRESH MATERIALIZED VIEW CONCURRENTLY mv_t1_t2 WITH DATA;
mytest=# insert into t1 values (12,'xx','yy');
mytest=# insert into t2 values (12,'xx','yy','zz');
mytest=# REFRESH MATERIALIZED VIEW CONCURRENTLY mv_t1_t2 WITH DATA;
mytest=# select * from mv_t1_t2 ;
t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
1 | 1 | a | b | c | d | e
2 | 2 | a | b | c | d | e
3 | 3 | a | b | c | d | e
4 | 4 | a | b | c | d | e
5 | 5 | a | b | c | d | e
11 | 11 | x | y | x | y | z
12 | 12 | xx | yy | xx | yy | zz
(7 rows)
物化视图刷新WITH NO DATA ,查询会报错
mytest=# REFRESH MATERIALIZED VIEW mv_t1_t2 WITH NO DATA;
mytest=# select * from mv_t1_t2 ;
ERROR: materialized view "mv_t1_t2" has not been populated
HINT: Use the REFRESH MATERIALIZED VIEW command.
mytest=# REFRESH MATERIALIZED VIEW mv_t1_t2 WITH DATA;
REFRESH MATERIALIZED VIEW
mytest=# select * from mv_t1_t2 ;
t1_id | t2_id | col1 | col2 | col3 | col4 | col5
-------+-------+------+------+------+------+------
1 | 1 | a | b | c | d | e
2 | 2 | a | b | c | d | e
3 | 3 | a | b | c | d | e
4 | 4 | a | b | c | d | e
5 | 5 | a | b | c | d | e
11 | 11 | x | y | x | y | z
12 | 12 | xx | yy | xx | yy | zz
(7 rows)