mysql存储地理信息的方法

mysql · 浏览次数 : 0

小编点评

**数据库表结构:** | 表名 | 数据类型 | 数据列 | |---|---|---| | locations | POINT | position | | polygons | POLYGON | shape | | points | POINT | position | **插入地理信息数据:** ```sql INSERT INTO locations (name, position) VALUES ('Location A', GeomFromText('POINT(10 20)')); INSERT INTO locations (name, position) VALUES ('Location B', PointFromText('POINT(30 40)')); ``` **查询地理信息数据:** 1. **MBRContains()函数:** ```sql SELECT * FROM locations WHERE MBRContains( GeomFromText('POLYGON((0 0, 20 0, 20 20, 0 20, 0 0))'), position ); ``` 2. **Distance_Sphere()函数:** ```sql SELECT *, (6371 * acos(cos(radians(15)) * cos(radians(X(position))) * cos(radians(Y(position)) - radians(15)) + sin(radians(15)) * sin(radians(X(position))))) AS distance_km FROM locations HAVING distance_km < 10; ``` 3. **ST_Distance_Sphere()函数:** ```sql SELECT *, ST_Distance_Sphere(point(15, 15), position, 6371) AS distance_km FROM locations HAVING distance_km < 10; ``` **查询地理信息进阶示例:** ```sql -- 创建一个包含多边形列的表 CREATE TABLE polygons ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, shape POLYGON NOT NULL, SPATIAL INDEX(shape) ) ENGINE=InnoDB; -- 插入多边形数据 INSERT INTO polygons (name, shape) VALUES ('Polygon A', GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')); INSERT INTO polygons (name, shape) VALUES ('Polygon B', GeomFromText('POLYGON((20 20, 30 20, 30 30, 20 30, 20 20))')); ``` **检查点是否在多边形内部,并计算距离:** ```sql SELECT p.name AS point_name, p.position, CASE WHEN ST_Contains(pg.shape, p.position) THEN 'Inside' ELSE 'Outside' END AS location_status, ST_Distance_Sphere(p.position, CASE pg.name WHEN 'Polygon A' THEN @polygonA_center ELSE @polygonB_center END, 6371) AS distance_km FROM points p JOIN polygons pg ON ( (p.name = 'Point 1' AND pg.name = 'Polygon A') OR (p.name = 'Point 2' AND pg.name = 'Polygon B') ); ```

正文

MySQL 存储地理信息通常使用 GEOMETRY 数据类型或其子类型(如 POINT, LINESTRING, POLYGON 等)。为了支持这些数据类型,MySQL 提供了 SPATIAL 索引,这允许我们执行高效的地理空间查询。

1. 创建支持地理信息的表

首先,我们需要一个包含 GEOMETRY 或其子类型列的表。以下是一个示例,展示如何创建一个包含 POINT 类型的表:

CREATE TABLE locations (  
    id INT AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(255) NOT NULL,  
    position POINT NOT NULL,  
    SPATIAL INDEX(position)  -- 为位置列创建空间索引  
) ENGINE=InnoDB;

2. 插入地理信息数据

我们可以使用 GeomFromText()PointFromText() 函数插入地理数据。以下是如何插入一个点的示例:

INSERT INTO locations (name, position)  
VALUES ('Location A', GeomFromText('POINT(10 20)'));  
-- 或者使用 PointFromText  
INSERT INTO locations (name, position)  
VALUES ('Location B', PointFromText('POINT(30 40)'));

3. 查询地理信息数据

我们可以使用 MBRContains(), Distance_Sphere(), ST_Distance_Sphere() 等函数来查询地理数据。以下是一些示例:

3.1查找指定矩形区域内的位置

-- 查找位置在 (0, 0) 到 (20, 20) 矩形区域内的所有位置  
SELECT * FROM locations  
WHERE MBRContains(  
    GeomFromText('POLYGON((0 0, 20 0, 20 20, 0 20, 0 0))'),  
    position  
);

3.2查找距离特定点一定距离内的位置

注意:这里使用了 Distance_Sphere() 函数,它基于地球是完美球体的假设。对于更精确的计算,我们可以使用 ST_Distance_Sphere() 并指定地球半径。

-- 查找距离 (15, 15) 点 10 公里内的所有位置  
-- 假设地球半径为 6371 公里(平均半径)  
SELECT *, (6371 * acos(cos(radians(15))   
  * cos(radians(X(position)))   
  * cos(radians(Y(position)) - radians(15))   
  + sin(radians(15))   
  * sin(radians(X(position))))) AS distance_km   
FROM locations   
HAVING distance_km < 10;

3.3使用 ST_Distance_Sphere() 查找距离

这是一个更精确的距离计算示例,它使用 ST_Distance_Sphere() 函数并指定地球的平均半径。

-- 查找距离 (15, 15) 点 10 公里内的所有位置  
SELECT *, ST_Distance_Sphere(point(15, 15), position, 6371) AS distance_km   
FROM locations   
HAVING distance_km < 10;

注意:上述查询中的距离计算是基于 Haversine 公式的简化版本,它假设地球是一个完美的球体。在实际应用中,我们可能需要使用更复杂的算法来考虑地球的不规则形状。

此外,我们还可以使用 MySQL 的其他地理空间函数和操作符来执行更复杂的地理空间查询和操作。

4.查询地理信息进阶示例

我们可以探讨一个更复杂的示例,该示例涉及POLYGON地理数据类型,并使用ST_Contains函数来检查一个点是否位于多边形内部。同时,我们也会使用ST_Distance_Sphere函数来计算点与多边形中心点的距离。

4.1创建表并插入数据

首先,我们创建一个包含POLYGON列的表,并插入一些多边形数据。

CREATE TABLE polygons (  
    id INT AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(255) NOT NULL,  
    shape POLYGON NOT NULL,  
    SPATIAL INDEX(shape)  
) ENGINE=InnoDB;  
  
INSERT INTO polygons (name, shape)  
VALUES ('Polygon A', GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'));  
INSERT INTO polygons (name, shape)  
VALUES ('Polygon B', GeomFromText('POLYGON((20 20, 30 20, 30 30, 20 30, 20 20))'));  
  
-- 创建一个包含点的表  
CREATE TABLE points (  
    id INT AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(255) NOT NULL,  
    position POINT NOT NULL,  
    SPATIAL INDEX(position)  
) ENGINE=InnoDB;  
  
INSERT INTO points (name, position)  
VALUES ('Point 1', GeomFromText('POINT(5 5)'));  
INSERT INTO points (name, position)  
VALUES ('Point 2', GeomFromText('POINT(25 25)'));

4.2查询点是否在多边形内部,并计算距离

现在,我们可以编写一个查询来检查点是否位于多边形内部,并计算这些点与多边形中心点的距离。

-- 假设我们想要检查'Point 1'和'Point 2'是否分别位于'Polygon A'和'Polygon B'内部  
-- 并计算它们与各自多边形中心点的距离  
  
-- 首先,我们需要计算每个多边形的中心点  
SET @polygonA_center = ST_Centroid(GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'));  
SET @polygonB_center = ST_Centroid(GeomFromText('POLYGON((20 20, 30 20, 30 30, 20 30, 20 20))'));  
  
-- 然后,我们可以使用这些中心点与点表中的点进行比较和距离计算  
SELECT   
    p.name AS point_name,  
    p.position,  
    CASE   
        WHEN ST_Contains(pg.shape, p.position) THEN 'Inside'  
        ELSE 'Outside'  
    END AS location_status,  
    ST_Distance_Sphere(p.position, CASE pg.name WHEN 'Polygon A' THEN @polygonA_center ELSE @polygonB_center END, 6371) AS distance_km  
FROM   
    points p  
JOIN   
    polygons pg ON (  
        (p.name = 'Point 1' AND pg.name = 'Polygon A') OR  
        (p.name = 'Point 2' AND pg.name = 'Polygon B')  
    );

这个查询首先计算了两个多边形的中心点,并使用JOIN语句将点表与多边形表连接起来。它使用ST_Contains函数来检查点是否位于多边形内部,并使用ST_Distance_Sphere函数来计算点与对应多边形中心点的距离(以公里为单位)。注意,我们使用了CASE语句来根据点的名称选择正确的多边形中心点进行计算。

这个查询将返回每个点的名称、位置、是否在多边形内部的状态以及与对应多边形中心点的距离。

与mysql存储地理信息的方法相似的内容:

mysql存储地理信息的方法

MySQL 存储地理信息通常使用 GEOMETRY 数据类型或其子类型(如 POINT, LINESTRING, POLYGON 等)。为了支持这些数据类型,MySQL 提供了 SPATIAL 索引,这允许我们执行高效的地理空间查询。 1. 创建支持地理信息的表 首先,我们需要一个包含 GEOMET

MySQL 存储函数及调用

本文主要介绍了MySQL存储函数及调用的方法,介绍了存储函数的示例,如何在MySQL中创建存储函数,以及介绍了MySQL中如何创建触发器,简简单单,一目了然。

MySQL之InnoDB存储结构

InnoDB存储引擎最早由Innobase Oy公司开发(属第三方存储引擎)。从MySQL 5.5版本开始作为表的默认存储引擎。该存储引擎是第一个完整支持ACID事务的MySQL存储引擎,特点是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,非常适合OLTP场景的应用使用。目前也是应用最广泛的存储引擎。

使用MySQL存储过程提高数据库效率和可维护性

MySQL 存储过程是一种强大的数据库功能,它允许你在数据库中存储和执行一组SQL语句,类似于编程中的函数。存储过程可以大幅提高数据库的性能、安全性和可维护性。本文将详细介绍MySQL存储过程的使用。 什么是MySQL存储过程? MySQL存储过程是一组预编译的SQL语句,它们以一个名称存储在数据库

MySQL存储过程、索引、分表对比

MySQL存储过程、索引和分表是用于提高查询效率的三种不同方法,它们各自对查询效率有不同的影响和应用场景。以下是它们的对比: MySQL存储过程: 影响查询效率: 存储过程通常不直接影响查询效率,因为它们是用于封装查询逻辑和执行多个SQL语句的数据库对象。存储过程主要有助于减少网络通信的开销,特别是

[转帖]第五章 MySQL 存储引擎

第五章 MySQL 存储引擎 https://www.jianshu.com/p/d12191803f17 本课程,适合具备一定Linux运维或者开发基础的朋友,课程定级中、高级DBA。只要掌握80%,轻松助力薪资15k-25K。课程内容均来自与MySQL官网+MySQL源码。配套精品视频(2021

MySQL高级10-InnoDB引擎存储架构

一、逻辑存储结构 表空间(Tablespace):一个mysql实例,及一个数据库实例,可以对应多个表空间(ibd文件),用于存储记录,索引等数据。 段(Segment):分为数据段(Leaf node segment)、索引段(Non-leaf node segment)、回滚段(Rollback

【后端面经-数据库】MySQL的存储引擎简介

对于mysql中常用的四类存储引擎MyISAM、InnoDB、MEMORY、MERGE的介绍和性能对比。

[转帖]深入理解mysql-第六章 mysql存储引擎InnoDB的索引-B+树索引

一、引入索引 在没有索引的情况下,不论是根据主键列或者其他列的值进行查找,由于我们并不能快速的定位到记录所在的页,所以只能从第一个页沿着双向链表一直往下找,因为要遍历所有的数据页,时间复杂度就是O(n),所以这种方式显然是超级耗时的。所以我们需要采取一定的数据结构来存储数据,方便我们进行数据的增删改

[转帖]【建议收藏】15755 字,讲透 MySQL 性能优化(包含 MySQL 架构、存储引擎、调优工具、SQL、索引、建议等等)

https://my.oschina.net/jiagoushi/blog/5593246 0. 目录 1)MySQL 总体架构介绍 2)MySQL 存储引擎调优 3)常用慢查询分析工具 4)如何定位不合理的 SQL 5)SQL 优化的一些建议 1 MySQL 总体架构介绍 1.1 MySQL 总体