MySQL 实战(一):实现“附近的人”功能

❤️ 个人主页:水滴技术
🚀 支持水滴:点赞👍 + 收藏⭐ + 留言💬
🌸 订阅专栏:MySQL 教程:从入门到精通

文章目录

  • ST_Distance_Sphere 函数
    • 示例一:计算北京站到北京西站的距离
    • 示例二:查询“附近的人”
  • Haversine 公式
    • 示例一:计算北京站到北京西站的距离
    • 示例二:查询“附近的人”
  • 总结
  • 热门专栏


大家好,我是水滴~~

对于“附近的人”功能,在生活中是比较常用的,像外卖app附近的美食,共享单车app里附近的车辆等等。我们之前使用 ElasticSearch 实现过该功能,本篇文章我们介绍如何通过 MySQL 来实现“附近的人”功能。

在这里插入图片描述

ST_Distance_Sphere 函数

在 MySQL 中,ST_Distance_Sphere 函数是一个地理空间函数,用于计算两个地理位置之间的球面距离。它基于球体模型进行计算,并返回两个点之间的距离结果。

ST_Distance_Sphere 函数的语法如下:

ST_Distance_Sphere(point1, point2)

其中,point1point2 是表示地理位置的 POINT 类型的参数。

示例一:计算北京站到北京西站的距离

以下是一个使用 ST_Distance_Sphere 函数计算球面距离的示例:

-- 北京站 116.427322,39.902822    北京西站  116.322083,39.8949
SELECT ST_Distance_Sphere(POINT(116.427322,39.902822), POINT(116.322083,39.8949)) AS distance;

在上述示例中,我们使用 POINT 类型的参数表示两个地理位置点,分别是北京站(经度 116.427322,纬度 39.902822)和北京西站(经度 116.322083,纬度 39.8949)。然后,我们调用 ST_Distance_Sphere 函数来计算这两个点之间的球面距离,并将结果命名为 distance

返回结果:

distance
-----------------------
9020.641566063772

ST_Distance_Sphere 函数的返回值是以米为单位的球面距离,可以根据需要将结果转换为千米。上面示例中可以看出,北京站到北京西站的距离约为9公里。

需要注意的是,使用 ST_Distance_Sphere 函数进行球面距离计算需要 MySQL 版本 8.0.17 或更高版本,并且需要在数据库中启用地理空间功能。

示例二:查询“附近的人”

要实现"附近的人"功能,可以使用MySQL的ST_Distance_Sphere 函数和索引来处理地理位置数据。下面是一个基本的实现步骤:

(1)创建GEO测试表:其中包括id 主键、location地理位置信息。地理位置信息可以使用POINT类型来表示。

CREATE TABLE `test_geo` (`id` bigint NOT NULL AUTO_INCREMENT,`location` point DEFAULT NULL,PRIMARY KEY (`id`)
);

(2)添加地理位置数据:向表中插入地理位置数据。

INSERT INTO `test_geo`(`id`, `location`) 
VALUES (1, POINT(116.39775,39.92029)),(2, POINT(116.395947,39.916208),(3, POINT(116.410624,39.91871)),(4, POINT(116.397235,39.909823)),(5, POINT(116.385304,39.917591)),(6, POINT(116.396548,39.92832))
;

(3)创建地理索引:为该表的地理位置字段创建索引,以便进行空间查询。

CREATE SPATIAL INDEX idx_location ON test_geo (location);

(4)查询附近的人:使用地理空间函数进行附近的人查询。

  SELECT*,ST_Distance_Sphere ( POINT ( 116.410539, 39.912983 ), location ) AS distance -- 返回距离,单位MFROMtest_geo WHEREST_Distance_Sphere ( POINT ( 116.410539, 39.912983 ), location ) <= 2000 -- 两公里内ORDER BYdistance -- 由近及远排序; 

上述查询使用了ST_Distance_Sphere函数来计算两个地理位置之间的球面距离,POINT ( 116.410539, 39.912983 ) 是你的坐标,2000是查询半径。这个查询将返回在给定半径范围内的数据。

查询结果:

在这里插入图片描述

Haversine 公式

ST_Distance_Sphere 函数要求MySQL 的版本为 8.0.17 或更高,对于低版本的 MySQL 该怎么办呢?我们可以使用 Haversine 公式来实现。

Haversine 是一种常用的球面三角函数,用于计算两个球面位置之间的球面距离。它是根据地球的球体模型进行计算的,可以用于近似计算两个经纬度坐标之间的球面距离。

Haversine 公式基于球面三角学和经纬度之间的关系。它的公式如下:

a = sin²(Δlat/2) + cos(lat1) * cos(lat2) * sin²(Δlon/2)
c = 2 * atan2(√a,(1-a))
d = R * c

其中:

  • lat1lat2 是两个点的纬度(以弧度表示)。
  • lon1lon2 是两个点的经度(以弧度表示)。
  • Δlat 是纬度之差,即 lat2 - lat1
  • Δlon 是经度之差,即 lon2 - lon1
  • R 是地球的半径,常用的单位是千米或英里。

通过应用 Haversine 公式,可以近似计算出两个经纬度坐标之间的球面距离。这个公式考虑了球体的曲率,因此对于较短距离的计算具有较高的精度。然而,对于较长距离,特别是跨越大片陆地或海洋的距离,Haversine 公式可能会引入一定的误差。

在使用 Haversine 公式进行计算时,需要注意输入的经纬度必须使用弧度表示。如果经纬度是以度数表示,需要将其转换为弧度形式进行计算。

示例一:计算北京站到北京西站的距离

以下是一个使用Haversine公式计算球面距离的示例:

-- 北京站 116.427322,39.902822    北京西站  116.322083,39.8949
select (2 * 6371 * ASIN(SQRT(POWER(SIN((RADIANS(39.902822) - RADIANS(39.8949)) / 2), 2) +COS(RADIANS(39.902822)) * COS(RADIANS(39.8949)) * POWER(SIN((RADIANS(116.427322) - RADIANS(116.322083)) / 2), 2)))) AS distance

在上述示例中,我们分别将北京站(经度 116.427322,纬度 39.902822)和北京西站(经度 116.322083,纬度 39.8949)的经纬度数据带入Haversine公式中,然后就可以计算出这两个点之间的球面距离,并将结果命名为 distance

返回结果:

distance
-----------------------
9.020661388581411

Haversine公式的返回值是以千米为单位的球面距离。

示例二:查询“附近的人”

我们可以使用Haversine公式来实现"附近的人"功能,下面是一个基本的实现步骤:

(1)创建GEO测试表:其中包括id 主键、地理位置信息。地理位置信息可以使用lng表示经度,lat表示纬度。

CREATE TABLE `test_geo` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`lng` double DEFAULT NULL,`lat` double DEFAULT NULL,PRIMARY KEY (`id`)
);

(2)添加地理位置数据:向表中插入地理位置数据。

INSERT INTO `test_geo`(`id`, `lng`, `lat`) 
VALUES (1, 116.39775, 39.92029),(2, 116.395947, 39.916208),(3, 116.410624, 39.91871),(4, 116.397235, 39.909823),(5, 116.385304, 39.917591),(6, 116.396548, 39.92832)
;

(3)查询附近的人:使用Haversine公式进行附近的人查询。

 SELECT*,(2 * 6371 * ASIN(SQRT(POWER( SIN(( RADIANS( 39.912983 ) - RADIANS( lat )) / 2 ), 2 ) + COS(RADIANS( 39.912983 )) * COS(RADIANS( lat )) * POWER( SIN(( RADIANS( 116.410539 ) - RADIANS( lng )) / 2 ), 2 ) ))) AS distance  -- 返回距离,单位KM
FROMtest_geo 
WHERE(2 * 6371 * ASIN(SQRT(POWER( SIN(( RADIANS( 39.912983 ) - RADIANS( lat )) / 2 ), 2 ) + COS(RADIANS( 39.912983 )) * COS(RADIANS( lat )) * POWER( SIN(( RADIANS( 116.410539 ) - RADIANS( lng )) / 2 ), 2 ) ))) <= 2  -- 两公里内
ORDER BYdistance -- 由近及远排序
;

上述查询使用了Haversine公式来计算两个地理位置之间的球面距离,116.410539, 39.912983 是你的坐标,2是查询半径。这个查询将返回在给定半径范围内的数据。

查询结果:

在这里插入图片描述

总结

使用 MySQL 来实现“附近的人”功能,可以通过Haversine 公式和ST_Distance_Sphere 函数两种方式来实现。对于低版本的 MySQL 只能使用Haversine 公式,但我们还是推荐升级你的 MySQL(8.0.17版本或更新),因为使用ST_Distance_Sphere 函数不仅使用简单,而且它还支持空间索引,使得查询速度更快。

热门专栏

👍 《Python入门核心技术》
👍 《IDEA 教程:从入门到精通》
👍 《Java 教程:从入门到精通》
👍 《MySQL 教程:从入门到精通》
👍 《大数据核心技术从入门到精通》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/56112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习】实验03 特征处理

文章目录 特征处理标准化归一化正则化 特征处理 标准化 # 导入标准化库 from sklearn.preprocessing import StandardScalerfrom matplotlib import gridspec import numpy as np import matplotlib.pyplot as plt import warnings warnings.filterwarnings("ignore&quo…

aws PinPoint发附件demo

php 版aws PinPoint发附件demo Laravel8框架&#xff0c;安装了"aws/aws-sdk-php": "^3.257" 主要代码&#xff1a; public function sendRawMail(Request $request) {$file $request->file(attachment);/*echo count($file);dd($file);*/$filenam…

Mobx在非react组件中修改数据,在ts/js中修改数据实现响应式更新

我们都之前在封装mobx作为数据存储的时候&#xff0c;使用到了useContext作为包裹&#xff0c;将store变成了一个hooks使用&#xff0c;封装代码: import React from react import UserInfo from ./user import Setting from ./seting import NoteStore from ./noteclass Stor…

基于Jenkins构建生产CICD环境(第三篇)

目录 基于Jenkins自动打包并部署docker环境 1、安装docker-ce 2、阿里云镜像加速器 3、构建tomcat 基础镜像 4、构建一个Maven项目 基于Jenkins自动化部署PHP环境 基于rsync部署 基于Jenkins自动打包并部署docker环境 1、安装docker-ce 在192.168.2.123 机器上&#x…

Go 第三方库引起的线上问题、如何在线线上环境进行调试定位问题以及golang开发中各种问题精华整理总结

Go 第三方库引起的线上问题、如何在线线上环境进行调试定位问题以及golang开发中各种问题精华整理总结。 01 前言 在使用 Go 语言进行 Web 开发时&#xff0c;我们往往会选择一些优秀的库来简化 HTTP 请求的处理。其中&#xff0c;go-resty 是一个被广泛使用的 HTTP 客户端。…

如何有效进行RLHF的数据标注?

编者按&#xff1a;随着大语言模型在自然语言处理领域的广泛应用&#xff0c;如何从人类反馈进行强化学习&#xff08;RLHF&#xff09;已成为一个重要的技术挑战。并且RLHF需要大量高质量的人工数据标注&#xff0c;这是一个非常费力的过程。 本文作者在数据标注领域具有丰富经…

解决jupyter notebook可以使用pytorch而Pycharm不能使用pytorch的问题

之前我是用的这个目录下的Python 开始更新目录 1、 2、 3、

【javaweb】学习日记Day6 - Mysql 数据库 DDL DML

之前学习过的SQL语句笔记总结戳这里→【数据库原理与应用 - 第六章】T-SQL 在SQL Server的使用_Roye_ack的博客-CSDN博客 目录 一、概述 1、如何安装及配置路径Mysql&#xff1f; 2、SQL分类 二、DDL 数据定义 1、数据库操作 2、IDEA内置数据库使用 &#xff08;1&…

Python3 列表

Python3 列表 序列是 Python 中最基本的数据结构。 序列中的每个值都有对应的位置值&#xff0c;称之为索引&#xff0c;第一个索引是 0&#xff0c;第二个索引是 1&#xff0c;依此类推。 Python 有 6 个序列的内置类型&#xff0c;但最常见的是列表和元组。 列表都可以进…

飞腾uboot命令简单介绍

飞腾uboot和开源uboot并无大差异,故飞腾uboot固件命令可以直接从网上搜索开源uboot相关命令。 这里为了便于大家调试,将一些可能用到的命令说明一下。 在 Uboot 命令行下,输入 help 将打印所有的可用命令,复杂命令操作,通过命令 help 的方式获取具体说明。 1.help命令 …

时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价)

时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价) 目录 时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价)效果一览基本描述程序设计参考资料 效果一览 基本描述 MATLAB实现DBN-SVM深度置信网络结合支持向量机…

校招算法题实在不会做,有没有关系?

文章目录 前言一、校招二、时间复杂度1、单层循环2、双层循环 三、空间复杂度四、数据结构五、校招算法题实在不会做&#xff0c;有没有关系&#xff1f;六、英雄算法集训 前言 英雄算法联盟八月集训 已经接近尾声&#xff0c;九月算法集训将于 09月01日 正式开始&#xff0c;目…

.NET 8 Preview 7 中的 ASP.NET Core 更新

作者&#xff1a;Daniel Roth 排版&#xff1a;Alan Wang .NET 8 Preview 7 现在已经发布&#xff0c;其中包括了对 ASP.NET Core 的许多重要更新。 以下是预览版本中新增功能的摘要&#xff1a; 服务器和中间件 防伪中间件 API 编写 最小 API 的防伪集成 Native AOT 请求委托…

市值暴跌后,每日优鲜能否靠2亿融资“续命”?

濒临破产退市的每日优鲜&#xff0c;靠转型实现“自救”&#xff1f; 作为“生鲜电商第一股”&#xff0c;每日优鲜在上市1年后爆发生存危机。 8月4日&#xff0c;每日优鲜(NDAQ:MF)公布了2022年报&#xff0c;尽管去年7月其宣布关闭营收占比约90%的DWM业务&#xff0c;全面终…

【80天学习完《深入理解计算机系统》】第十一天 3.5 过程(函数调用)

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

RK3568 安卓源码编译

一.repo安卓编译工具 项目模块化/组件化之后各模块也作为独立的 Git 仓库从主项目里剥离了出去&#xff0c;各模块各自管理自己的版本。Android源码引用了很多开源项目&#xff0c;每一个子项目都是一个Git仓库&#xff0c;每个Git仓库都有很多分支版本&#xff0c;为了方便统…

gradio使用transformer模块demo介绍2:Images Computer Vision

文章目录 图像分类 Image Classification图像分割 Image Segmentation图像风格变换 Image Transformation with AnimeGAN3D模型 3D models 图像分类 Image Classification import gradio as gr import torch import requests from torchvision import transformsmodel torch.…

【Unity3D赛车游戏】【六】如何在Unity中为汽车添加发动机和手动挡变速?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

【【STM32分析IO该设置什么模式的问题】】

STM32分析IO该设置什么模式的问题 我们分析而言 我们对于PA0 的设计就从此而来 对于边沿触发的选择我们已经有所了解了 我们下拉&#xff0c;但是当我们摁下开关的时候 从0到1 导通了 所以这个是下拉 上升沿触发 而对于KEY0 我们摁下是使得电路从原来悬空高阻态到地就是0 所以…

龙芯2K1000LA移植交叉编译环境以及QT

嵌入式大赛结束了&#xff0c;根据这次比赛中记的凌乱的笔记&#xff0c;整理了一份龙芯2K1000LA的环境搭建过程&#xff0c;可能笔记缺少了一部分步骤或者错误&#xff0c;但是大致步骤可以当作参考。 一、交叉编译工具链 下载连接&#xff1a;龙芯 GNU 编译工具链 | 龙芯开…