标签: spatial

创建空间索引的权限

在表上创建空间索引所需的权限,对于这个BOL 说

需要对表或视图具有 ALTER 权限。用户必须是 sysadmin 固定服务器角色或 db_ddladmin 和 db_owner 固定数据库角色的成员。

但是,我发现单独的Alter 权限足以在表上创建空间索引。(没有服务器系统管理员权限)

我在下面创建的测试:(运行每个批次以了解发生了什么)

USE adventureworks;
GO
/* Start these scripts with a priveledged account */

CREATE TABLE employees
(employeedid INT PRIMARY KEY IDENTITY(1,1),
empaddress GEOGRAPHY
)
INSERT INTO employees VALUES(geography::STGeomFromText('LINESTRING(47.656 -12.360, 47.656 -12.343)', 4326))
GO

/* Create our test SQL account with limited access = no securables yet */
CREATE LOGIN LimitedPerms WITH Password = 'pass';
CREATE USER LimitedPerms FOR LOGIN LimitedPerms;
GO

EXEC AS …
Run Code Online (Sandbox Code Playgroud)

index sql-server spatial

6
推荐指数
1
解决办法
590
查看次数

SQL Server 点构造函数或 ST_Point(x,y) 版本?

PostGIS 提供了两个点构造函数

MySQL 支持 Point(x,y)

在 SQL Server 中,有没有先从两个数字输入或实数构造一个点而不先从文本开始?

我在“创建、构造和查询几何实例”的文档中没有看到采用数字的构造函数。

sql-server spatial

6
推荐指数
1
解决办法
2498
查看次数

SQL Server 行构造函数或 ST_MakeLine(pt1,pt2) 版本?

PostGIS 提供了一个名为ST_MakeLine(pt1,pt2). 它非常适合构建线条。MySQL 对LineString(pt1,pt2). 什么叫 SQL Server 模拟,它需要两个点并构造一个 LineString?

了一下LineString,但没有看到提到它。

这是一个关于 dbfiddle 的测试用例

样本数据,

CREATE TABLE #tmp (
  pt1 geometry,
  pt2 geometry,
);

INSERT INTO #tmp(pt1,pt2) VALUES
  (geometry::Point(1,1,4326), geometry::Point(2,2,4326)),
  (geometry::Point(2,2,4326), geometry::Point(5,5,4326)),
  (geometry::Point(3,3,4326), geometry::Point(4,4,4326)),
  (geometry::Point(4,4,4326), geometry::Point(3,3,4326)),
  (geometry::Point(5,5,4326), geometry::Point(4,4,4326));
Run Code Online (Sandbox Code Playgroud)

询问

SELECT pt1, pt2
  'My Line' AS line -- what goes here
FROM #tmp;
Run Code Online (Sandbox Code Playgroud)

我希望“My Line”成为LineString.

pt1         pt2         line
POINT (1 1) POINT (2 2) My Line
POINT (2 2) POINT …
Run Code Online (Sandbox Code Playgroud)

sql-server spatial

6
推荐指数
1
解决办法
643
查看次数

如何强制 SQL Server 通过视图使用我的空间索引?

我有一些表,其中包含存储为 lat long 对的属性的事务。(然后在我的示例架构中有更多的列和数据点)。

一个常见的请求是查找特定点 X 英里范围内发生的交易,并且只检索附近每个房产发生的 5 个最近的交易。

为了完成这项工作,我决定添加一个视图来封装最新的逻辑:

create or alter view dbo.v_example
with schemabinding as
select example_id
      ,transaction_dt
      ,latitude
      ,longitude
      ,latlong
      ,most_recent= iif(row_number() over (partition by latitude,longitude order by transaction_dt desc) < 5,1,null)
from dbo.example;
Run Code Online (Sandbox Code Playgroud)

所以一个查询可能看起来像这样:

create or alter view dbo.v_example
with schemabinding as
select example_id
      ,transaction_dt
      ,latitude
      ,longitude
      ,latlong
      ,most_recent= iif(row_number() over (partition by latitude,longitude order by transaction_dt desc) < 5,1,null)
from dbo.example;
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我通过视图查询时,SQL Server 不想使用空间索引。如果我删除schemabinding并尝试在视图上添加提示,我会发现查询处理器无法创建计划。

如何封装逻辑并仍然让它使用我的空间索引?

这是一个带有示例数据和计划形状的 db<>fiddle

该表要大得多,扫描它然后进行聚集索引查找然后逐点查找要慢得多。

sql-server spatial sql-server-2016

6
推荐指数
1
解决办法
260
查看次数

当预期为 0 时,MSSQL Geography STIntersects 返回 1

我遇到了一个无法解释的 MSSQL 地理问题。假设我在数学上受到挑战,但似乎以下点不应与以下多边形相交:

DECLARE @t_point geography;  
DECLARE @t_polygon geography;
set @t_polygon = geography::STPolyFromText('POLYGON((1 1, 5 5, 5 0, 1 1))', 4326);
set @t_point = geography::Point(0, 0, 4326);


select
  @t_polygon.STAsText(), 
  @t_point.STAsText(),
  @t_point.STIntersects(@t_polygon), 
  @t_polygon.STIntersects(@t_point);
Run Code Online (Sandbox Code Playgroud)

但是,当我执行此操作时,会得到以下结果:

POLYGON ((1 1, 5 5, 5 0, 1 1))  POINT (0 0) 1   1
Run Code Online (Sandbox Code Playgroud)

最后两列都是 1,我期望为 0。空间中 0,0 处的点如何与不接触或包含 0,0 的多边形相交?

-1, -1 与 100, 100 具有相同的行为。

即使我将点更改为完全不同空间中的多边形,MSSQL 也会说它们相交。

set @t_polygon = geography::STPolyFromText('POLYGON((10 10, 50 50, 50 10, 10 10))', 4326);
set @t_point = geography::STPolyFromText('POLYGON((1 1, 5 …
Run Code Online (Sandbox Code Playgroud)

sql-server spatial

6
推荐指数
1
解决办法
293
查看次数

如何设计大洲、国家、地区、城市和 POI 的数据库?

我不是数据库设计师,所以我在设计带有 GIS 信息的数据库时遇到了麻烦。目标是创建一个包含大陆、国家、地区(包括州、子地区、省)、城市和城市中的地方的系统。这些元素中的每一个都将包含一些文本信息和相关内容。作为数据库,我们将使用 PostgreSQL 和 PostGIS。

我的问题是,我如何为这个系统设计数据库?我在考虑 2 个表polygonspoints,但我不确定这是否是好的思考方式。

实际上我们需要的是一些国家、城市、地区等之间关系的分层基础。该应用程序的主要目标是从许多来源收集关于特定城市、地区、国家等的旅游数据,并将其存储在数据库中。假设我们有一个城市罗马;我们从几个来源收集了一些关于这个城市的信息到数据库中。我们需要知道罗马位于罗马省,拉齐奥地区拉齐奥的次地区拉齐奥,国家意大利。所以系统应该是灵活的,允许我们从现实世界中创建这样的关系。

这就是为什么我会选择两个表:

  1. polygons - 可以存储国家、地区、子地区、省份等。
  2. points - 可以存储城市和兴趣点

postgresql database-design spatial

5
推荐指数
1
解决办法
2629
查看次数

限制在边界上的不重叠矩形

我正在尝试对电路板上零件的放置进行建模。没有任何有意义的限制,我的基本架构如下所示:

create table part (
    part_id bigserial primary key,
    name text not null,
    width double precision not null,
    height double precision not null
);
create table board (
    board_id bigserial primary key,
    width double precision not null,
    height double precision not null
);
create table board_part (
    board_id bigint not null references board,
    part_id bigint not null references part,
    position point not null
);
Run Code Online (Sandbox Code Playgroud)

SQL Fiddle可视化

对于bb2any board_parts,我想强制执行以下约束:

  1. b位于黑板上:

    box(b.position, …
    Run Code Online (Sandbox Code Playgroud)

postgresql database-design referential-integrity spatial exclusion-constraint

5
推荐指数
1
解决办法
529
查看次数

未使用空间索引

我有一个带geometry列的表。对于一个记录,只Point存储一个。已创建空间索引,但搜索最近位置的查询不使用此索引,从而导致性能不佳。

示例脚本:

--Create the table
create table Location(
    LocationID int not null identity(1,1) primary key,
    LocationPoint geometry
)


--add records
declare @counter int =0
WHILE @counter<150000
BEGIN
    set nocount on
    --select 
    set @counter =@counter +1
    declare @RandomLocation geometry=geometry::Point(RAND() *1000, RAND() *1000, 0)     
    insert into Location(LocationPoint) values  (@RandomLocation)   
END

--create index
CREATE SPATIAL INDEX SPATIAL_StructureBE ON dbo.Location(LocationPoint)
USING GEOMETRY_GRID WITH ( 
    BOUNDING_BOX  = (xmin  = 0.0, ymin  = 0.0, xmax  = 1000, ymax  = 1000), 
    GRIDS = …
Run Code Online (Sandbox Code Playgroud)

performance index sql-server spatial query-performance

5
推荐指数
1
解决办法
1352
查看次数

查询每组最近邻的空间数据

我想查询最近邻的空间数据。我正在使用这篇文章,以下查询完美运行:

SELECT TOP 1 [Location].STDistance(@Location)
FROM [DS1]
WHERE [Location].STDistance(@Location) IS NOT NULL          
ORDER BY [Location].STDistance(@Location);
Run Code Online (Sandbox Code Playgroud)

问题是我需要为每个MSPID. 我尝试了几件事(使用交叉应用,创建单独的函数等)但没有任何效果。所以,我决定创建一个循环来计算每个MSPID.

SELECT TOP 1 [Location].STDistance(@Location)
FROM [DS1]
WHERE [Location].STDistance(@Location) IS NOT NULL 
    AND @CurrentMSPID = [MSPID]         
ORDER BY [Location].STDistance(@Location);
Run Code Online (Sandbox Code Playgroud)

问题是上面的语句没有使用索引。如果我@CurrentMSPID用一个数字替换使用索引,但是当使用一个变量时,使用聚集索引而不是空间索引。

我尝试了很多选择,唯一有效的是:

OPTION (OPTIMIZE FOR ( @CurrentMSPID  = 1001 ))
Run Code Online (Sandbox Code Playgroud)

或者当值是硬编码时。我不能那样做,因为将来这id甚至可能不存在,并且肯定会更改它匹配的行数。

[DS1]表在[MSPID]列上有主键,在列上有空间索引[Location]

如何在不使用OPTIMIZE FOR选项的情况下帮助引擎生成更好的执行计划并使用空间索引?


当从表中提取其他数据时(我们MSPID现在正在过滤),引擎似乎无法使用空间索引并执行聚集索引查找。

sql-server sql-server-2012 spatial sql-server-2014 nearest-neighbor

5
推荐指数
1
解决办法
4244
查看次数

如何加快对地理位置过程的查询

我有一个包含 10,301,390 个 GPS 记录、城市、国家和 IP 地址块的表。我有用户当前的经纬度位置。我创建了这个查询:

SELECT
  *, point(45.1013021, 46.3021011) <@> point(latitude, longitude) :: point AS distance
FROM
  locs
WHERE
  (
    point(45.1013021, 46.3021011) <@> point(latitude, longitude)
  ) < 10 -- radius
ORDER BY
  distance LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

这个查询成功地给了我我想要的东西,但它很慢。根据给定的纬度和经度,获得一条记录需要 2 到 3 秒。

我在latitudelongitude列上尝试了 B 树索引,也尝试过,GIST( point(latitude, longitude));但查询仍然很慢。

我怎样才能加快这个查询?

更新:

似乎缓慢是由 引起的,ORDER BY但我想获得最短距离,所以问题仍然存在。

postgresql index spatial gist-index

5
推荐指数
1
解决办法
5761
查看次数