首页 > 数据库 >Oracle-Spatial空间数据库基础

Oracle-Spatial空间数据库基础

时间:2024-10-23 10:34:51浏览次数:1  
标签:sdo 数据库 空间 查询 索引 Spatial Oracle SDO

Oracle-Spatial空间数据库基础

完全转自:https://blog.csdn.net/wyp_666/article/details/72775714

一、简介 
oracle spatial是oracle公司推出的空间数据库组件,使oracle具备处理空间数据的能力。从9i开始对空间数据提供了比较完备的支持。Oracle Spatial主要通过元数据表、空间属性字段(SDO_GEOMETRY)和空间索引(R-tree和四叉树索引)来管理空间数据,并在此基础上提供一系列空间查询和空间分析的函数。

二、以上没啥用,意思就是: 
1.建好表(多了一个SDO_GEOMETRY类型的字段)、插入数据后、插入个元数据视图, 
2.空间属性字段就是空间表区别于其他表的标志,字段类型SDO_GEOMETRY(可以自定义) 
3.空间索引可以理解为从普通表的B树索引演化来的,用来提高查询速度,四叉树索(原理我理解为切豆腐),但是对空间对象分布不均匀时,就会因不均衡速度变慢,所以主要用R-树索引,对于这两种索引有空再整理。 
4.函数,部分依赖空间索引主要用来做查询,部分是不依赖索引的,所以当数据量大的时候就要先用依赖索引的函数快速缩小计算范围,然后再用空间分析函数计算想要的结果(刚开始用oracle-spatial的时候,用网上那些复制粘贴大神的方法,数据量大后就有问题了,后来受到上学时专业书内容的启发,想到一种办法,解决了查询不规则多边形内point的速度问题)

三、Oracle Spatial定义的SDO_GEOMETRY类型为:

CREATE TYPE SDO_GEOMETRY AS OBJECT (

                    SDO_GTYPE   NUMBER,  //前面字符串为字段名;后面字符串为字段类型

                     SDO_SRID    NUMBER,

                     SDO_POINT    SDO_POINT_TYPE,

                     SDO_ELEM_INFO    SDO_ELEM_INFO_ARRAY,

                     SDO_ORDINATES    SDO_ORDINATE_ARRAY);

其中SDO_GEOMETRY AS OBJECT ,标识该类型为对象类型。开始我们可以理解它为ArcObjects中的Geometry对象(本来要素的shape字段中的对象就是Geometry),而不要理解他是怎么样组织的。至于该类型中的SDO_POINT_TYPE、SDO_ELEM_INFO_ARRAY、SDO_ORDINATE_ARRAY也是Oracle Spatial自定义的类型和 sdo_geometry 是一样的。

  

现在对sdo_geometry 类型中的各个参数简单的介绍:

    1、SDO_GTYPE :表示要存储的几何类型,如点线面。它是通过 NUMBER类型来表达的;

    2、SDO_SRID :几何的空间参考坐标系,类型也为 NUMBER;

    3、SDO_POINT :如果几何类型点类型的话,就是存储点坐标,否则为空。oracle自定义的SDO_POINT_TYPE类型;

    4、SDO_ELEM_INFO :定义要如何理解SDO_ORDINATES中的坐标串的;

5、SDO_ORDINATES :存储实际坐标的,以X、Y以及不同点之间都是逗号隔开;

 

四、学习的时候看网上的不是复制粘贴,就是翻译翻译官网的例子,实际用还很不方便,下面直接说实际操作: 
–0.查看是否安装了oracle-spatial

SQL> desc sdo_georaster;

 

Element         Type              

RASTERTYPE      NUMBER            

SPATIALEXTENT   MDSYS.SDO_GEOMETRY

RASTERDATATABLE VARCHAR2(32)      

RASTERID        NUMBER            

METADATA        SYS.XMLTYPE 

这是装了,没装的话要手动装。

网上例子都是针对插入几条测试数据,公司实际用肯定需要批量插入, 
不同数据格式导入有不同方法:

MapInfo连接oracle后,mapinfo的文件可直接导入。 
ArcGIS的*.shp文件,需要使用Shp2SDO转换。

文本文件数据导入两种办法:

1.程序连接数据库一条条插(java-jdbc,python需要安装cx_oracle 模块); 
2.使用sqlldr批量插(但是每条数据需要拼成特殊格式);

背景: 
文本文件; 
一条数据样例(三个字段id|经度|纬度,’|’分隔):1|115.98346012774272|39.7059960734836 ; 
数据量2000万条;

提前处理数据,拼接结果: 
 
–1.建表

create table wyp_point_test(

id number,

geoloc sdo_geometry)

 

–2.sqlldr导入数据(这步sqlldr控制文件和普通表的控制文件是不一样的,要针对SDO_GEOMETRY 结构,这个网上没有,下面是点的例子,线和多边形的要修改控制文件和数据格式) 
控制文件point.ctl

load data

infile "/data1/all_signal_dev/wyp/allrsl.txt"

append

continueif next(1:1)='#'

into table china_subway_point

fields terminated by "|"

trailing nullcols(

id,

geoloc column object

(sdo_gtype,

sdo_srid,

sdo_point column object(

x,y)))

 

–3.导入数据后更新元数据试图

insert into user_sdo_geom_metadata(TABLE_NAME,COLUMN_NAME

,DIMINFO,SRID) values(

'wyp_point_test',

'geoloc',

mdsys.sdo_dim_array(

MDSYS.SDO_DIM_ELEMENT('x',70.000000000,140.000000000,0.000000050),

MDSYS.SDO_DIM_ELEMENT('y',0.000000000,60.000000000,0.000000050)),

8307--SRID

);

 

–4.创建索引

create index wyp_point_test_idx on wyp_point_test(geoloc)

indextype is mdsys.spatial_index

 

1)创建索引之前总是要为空间层插入元数据(更新元数据视图) 
2)如果之前创建的索引失败了,必须先删除才能创建

Drop index wyp_point_test_idx ;

在索引创建过程中,Oracle检查索引列的sdo_srid和user_sdo_geom_metadata中的srid是否匹配,如果不匹配,Oracle会产生ora-13365错误。 
空间索引信息可查看user_sdo_index_metadata或者较简单的user_sdo_index_info视图。 
空间索引表存储在这个SDO_INDEX_TABLE字段中,总是以MDRT开头。不能将一个空间索引表和普通的表一样对待-即不能将它从一个表空间移到另一个表空间,也不能将它删除、复制等。否则,会出现无效的空间索引并导致后续的空间查询操作符或空间索引重建失败。 
(R-树索引、四叉树索引原理、以及索引参数以后再说)

–5.空间查询和空间分析的函数 
函数,部分依赖空间索引主要用来做查询,部分是不依赖索引的就是空间分析函数,其实,函数到好学,一看就会,就是准备数据的部分,网上说的很少吗,所以主要说数据组织部分,函数简单说。

–SDO_WITHIN_DISTANCE 查询500米范围内的对象

SELECT id

FROM WYP_POINT_TEST A

WHERE SDO_WITHIN_DISTANCE(A.Geoloc,

                           MDSYS.SDO_GEOMETRY(2001,

                                              8307,

                                              MDSYS.SDO_POINT_TYPE(116.4601216738,39.9534043499, 0),

                                              NULL,

                                              NULL),

                            'distance=' || 500 || ' unit=m') = 'TRUE'

 

–SDO_FILTER、SDO_GEOM.RELATE 查询多边形内的point

SELECT

ID FROM WYP_POINT_TEST S  WHERE

SDO_FILTER(S.GEOLOC,MDSYS.SDO_GEOMETRY(2003,8307,NULL,

                                        MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),

                                        MDSYS.SDO_ORDINATE_ARRAY(113.6578611,34.74956944,113.6539528,34.75609722,113.6560056,34.75886667,113.6608,34.76098889,113.6660139,34.75729722,113.665475,34.75417222,113.66205,34.75011111,113.6578611,34.74956944)),

                                        'QUERYTYPE = WINDOW') = 'TRUE'

AND

SDO_GEOM.RELATE(MDSYS.SDO_GEOMETRY(2003,8307,NULL,

                                     MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),

                                     MDSYS.SDO_ORDINATE_ARRAY(113.6578611,34.74956944,113.6539528,34.75609722,113.6560056,34.75886667,113.6608,34.76098889,113.6660139,34.75729722,113.665475,34.75417222,113.66205,34.75011111,113.6578611,34.74956944)),

                                      'ANYINTERACT',

                                      S.GEOLOC,

                                      0.005)='TRUE'

 

6.重点:

1.上面两个例子都是都是用了个临时对象,也可以插入另一张表里。 
2.Oracle对sql的长度是有限制的,例如一个多边形的经纬度有500多对,临时对象的方法就不行了,我想到的解决办法是,先把多边形入到另一张空间表里,这样sql长度就没有限制了,还有个问题,入表里不能用insert into 需要使用sqlldr, 因为insert 同样是sql。。。 
3.SDO_GEOM.RELATE函数是不依赖索引的,所以数据量上千后就遍历很慢,困扰了很久,我做梦想到的办法就是,先通过索引查询出,多边形最小矩形内的点,再和多变形计算,需要使用RELATE计算的数据量巨减。 
4.使用SDO_WITHIN_DISTANCE 同样可以查询多边形周边以及内部的点,距离设置为0,不就是内部的点了嘛,大于0就是周边和内部的了,但有个细节,这么做是最好对查询出的结果算下点和多边形距离,因为实际用的时候发现,使用这种方法的多边形经纬度要逆时针排列,顺时针的话,数据出来是错的,差了十万八千里。 
5.2000万个点时,查询速度是秒级,平常用应该没什么问题。

7.个人总结的空见查询提高性能方法(仅供参考)

1.建立索引时,指明空间索引中的对象类型(点线面)

create index CELL_ADJ_ALL_idx on DIM_M_CELL_ADJ_ALL_SPATIAL(geoloc)

indextype is mdsys.spatial_index

PARAMETERS('layer_gtype=POINT') 

其中index_name为空间索引名,table_name为表名,row_name为列名,

layer_gtype的值除POINT外,还可以为LINE,POLYGON等。

 

2.利用表分区提高性能

当需要存储和检索的数据量庞大时,为了易于管理和提高空间数据检索的效率,可以在这个庞大的数据表中建立分区,

然后在这些分区表上建立空间索引,这样不仅使表易于管理,减少每次查询的查询数量。 

 

3.选择合理的空间操作符的参数次序   

在执行包含空间操作符的SQL语句时,Oracle会根据参数次序选择不同的执行计划。

因此,需根据查询对象的特点选择合理的参数次序,以便使Oracle Spatial选择较好的执行计划,

提高空间查询的效率。但是,并不是改变每个空间操作符的次序都可以提高空间查询的效率,

仅改变那些对参数次序敏感的空间操作符如SOD_WITHIN_DISTANCE才可以显著地提高空间查询效率.

之所以合理的空间操作符的参数次序可以提高空间查询的效率,主要在于Oracle Spatial的空间查询机制。

Oracle Spatial对空间查询使用双重查询机制,进行主过滤环节和次过滤环节。

调整空间操作符的参数次序可以使得主过滤阶段更充分的运用空间索引,从而提高空间查询的效率,缩短了空间查询

 

简单介绍一下sdo_Geom.Relate 吧

sdo_Geom.Relate(sdo_Geometry1, ‘MASK’, sod_Geometry2, tolerance ):

用于判断一个几何体与另一个几何体的关系,我们用于判断当前点是否在某一个面(省份面、县市面、乡镇面)上。

  参数说明:

    sdo_Geometry1,sdo_Geometry2为空间数据对应的几何对象。

    Tolerance: 容许的精度范围;

      MASK参数:

    Anyinteract: sdo_Geometry2落在sdo_Geometry1面上包括在边上。

    Contains: sdo_Geometry2完全包含在sdo_Geometry1几何对象中,并且两个几何对象的边没有交叉。

    Coveredby: sdo_Geometry1完全包含在sdo_Geometry2中,并且这两个几何对象的边有一个或多个点相互重叠。

    Covers: sdo_Geometry2完全包含在sdo_Geometry1中,并且这两个几何对象的边有一个或多个点相互重叠。

    Disjoint: 两个几何没有重叠交叉点,也没有共同的边。

    Equal: 两个几何是相等的。

    Inside: sdo_Geometry1完全包含在sdo_Geometry2几何对象中,并且两个几何对象的边没有交叉。

    On: sdo_Geometry1的边和内部的线完全在sdo_Geometry2上。

    Overlapbdydisjoint: 两个几何对象交迭,但是边没有交叉。

    Overlapbdyintersect: 两个几何对象交迭,并且边有部分交叉。

    Touch: 两个几何对象有共同的边,但没有交叉。

 

  标签: Oracle Spatial

标签:sdo,数据库,空间,查询,索引,Spatial,Oracle,SDO
From: https://www.cnblogs.com/sexintercourse/p/18495807

相关文章

  • 空间数据库基础理论 GIS空间数据处理分析涉及的基本概念
    空间数据库基础理论GIS空间数据处理分析涉及的基本概念周陆军​腾讯科技(深圳)有限公司前端开发​关注他 63人赞同了该文章《空间数据库》课程整理汇总,106篇课程,内容太长,学习中,把一些关键点,汇总记下笔记地理空间GIS中的地理空间(Geo-spatial)是指......
  • 一篇文章带你玩转PostGIS空间数据库
    一篇文章带你玩转PostGIS空间数据库发布于 2023-10-1714:35:555.4K0举报文章被收录于专栏:半旧的技术栈一篇文章带你玩转PostGIS空间数据库一、空间数据库介绍1.什么是空间数据库人类理解世界其实是按照三维的角度,而传统的关系型数据库是二维的,要......
  • SpatialDB:让空间转录组数据可视化
    SpatialDB:让空间转录组数据可视化原创修改于 2021-08-3115:30:101.3K0举报文章被收录于专栏:国家基因库生命大数据平台2019年11月,来自中国科学院生物物理研究所高通量测序中心的研究人员发布第一个单细胞空间转录组数据库及数据在线可视化平台:Spatial......
  • 空间索引Spatial Indexing
    空间索引SpatialIndexing李喆叫我桔子吧PhD(Database)​关注他 148人赞同了该文章大家第一次接触到index应该是在上数据库这门课的时候。之所以数据库需要index,主要是因为数据量和应用层面的操作这两个原因,缺一不可。回忆下数据库最基本的......
  • Oracle11g一键巡检脚本(输出HTML格式)
    脚本内容:#!/bin/bash#设置Oracle环境变量exportORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1exportORACLE_SID=orcl11gexportPATH=$ORACLE_HOME/bin:$PATHfunctionseparator(){localLine=Title=Bytes=Xlength=Title="$*"Line='......
  • 基于大数据 Python+Vue 电影票房爬取可视化系统(源码+LW+部署讲解+数据库+ppt)
    !!!!!!!!!会持续一直更新下去有问必答一键收藏关注不迷路源码获取:https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwd=jf1d提取码:jf1d!!!!!!!!!项目介绍在快速发展的社会中,娱乐领域也在不断进步。为了提高数据分析的效率和观众的观影体验,越来越多的影视公司和电影院选择利用互联网......
  • Java毕设项目案例实战II 基于移动平台的远程在线诊疗系统(开发文档+数据库+源码)
    目录一、前言二、技术介绍三、系统实现四、论文参考五、核心代码六、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言在当今数字化时代,医疗行业正经历着前所未......
  • 简单的数据库备份脚本
    数据库备份脚本是一种用于定期将数据库中的数据导出到一个文件中的程序,通常用于数据恢复或迁移的目的。数据库备份脚本可以根据不同的数据库类型和需求,采用不同的语言和工具编写,例如Shell、Python、MySQLdump等。本文将介绍如何编写一个简单的数据库备份脚本,并给出一个示例。编写......
  • .NET云原生应用实践(三):连接到PostgreSQL数据库
    本章目标实现基于PostgreSQL的SDAC(简单数据访问层)将Stickers微服务切换到使用PostgreSQLSDAC为什么选择PostgreSQL数据库?其实并不一定要选择PostgreSQL数据库,这里主要出于几个方面考虑:PostgreSQL免费易用,轻量效率高,能够满足目前的需求PostgreSQL生态成熟,资源丰富,遇到问......
  • 数据库脚本自动执行工具
    第一款:Evolve官网:https://evolve-db.netlify.app/requirements/仓库:https://github.com/lecaillon/Evolve提供了三种使用方式:类库:可以引入到现有的项目中nuget包:可以直接安装并在命令行中使用cli:可以不依赖.netsdk直接运行细节命名要求:前缀:仅执行一次的脚本以V开头,......