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

这篇具有很好参考价值的文章主要介绍了MySQL 实战(一):实现“附近的人”功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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


大家好,我是水滴~~

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

MySQL 实战(一):实现“附近的人”功能,MySQL 教程:从入门到精通,mysql,geo,空间索引,附近的人

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 -- 返回距离,单位M
  FROM
    test_geo 
  WHERE
    ST_Distance_Sphere ( POINT ( 116.410539, 39.912983 ), location ) <= 2000 -- 两公里内
  ORDER BY
    distance -- 由近及远排序
  ; 

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

查询结果:

MySQL 实战(一):实现“附近的人”功能,MySQL 教程:从入门到精通,mysql,geo,空间索引,附近的人

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
FROM
  test_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 BY
  distance -- 由近及远排序
;

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

查询结果:

MySQL 实战(一):实现“附近的人”功能,MySQL 教程:从入门到精通,mysql,geo,空间索引,附近的人

总结

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

热门专栏

👍 《Python入门核心技术》
👍 《IDEA 教程:从入门到精通》
👍 《Java 教程:从入门到精通》
👍 《MySQL 教程:从入门到精通》
👍 《大数据核心技术从入门到精通》文章来源地址https://www.toymoban.com/news/detail-667457.html

到了这里,关于MySQL 实战(一):实现“附近的人”功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch集群搭建、数据分片以及位置坐标实现附近的人搜索

    es使用两种不同的方式来发现对方: 广播 单播 也可以同时使用两者,但默认的广播,单播需要已知节点列表来完成 当es实例启动的时候,它发送了广播的ping请求到地址 224.2.2.4:54328 。而其他的es实例使用同样的集群名称响应了这个请求。 一般这个默认的集群名称就是上面的

    2024年02月06日
    浏览(52)
  • Jmeter(七) - 从入门到精通 - 建立数据库测试计划实战<MySQL数据库>(详解教程)

    1.简介   在实际工作中,我们经常会听到数据库的性能和稳定性等等,这些有时候也需要测试工程师去评估和测试,上一篇文章主要介绍了jmeter连接和创建数据库测试计划的过程,在文中通过示例和代码非常详细地介绍给大家,希望对各位小伙伴和童鞋们的学习或者工作具有一

    2024年02月13日
    浏览(58)
  • 全网最全Pytest框架使用教程和项目实战~从入门到精通

    pytest是一个非常成熟的python单元测试框架,比unittest更灵活、更容易上手 pytest可以和selenium、requests、appinum结合实现web自动化、接口自动化、app自动化 pytest可以是实现测试用例的跳过以及reruns失败用例重试 pytest可以和aliure生成非常美观的测试报告 pytest可以和jenkins持续集成

    2024年02月06日
    浏览(47)
  • Jmeter(五) - 从入门到精通 - 创建网络计划实战和创建高级Web测试计划(详解教程)

    1.简介 上一篇中已经将其的理论知识介绍了一下,这一篇就带着大家一步一步的把上一篇介绍的理论知识实践一下,然后再说一下如何创建高级web测试计划。 2.网络计划实战 通过上一篇的学习,将其分类为: (1)不需要登录验证身份就可以操作的。 (2)需要登录验证身份

    2024年02月13日
    浏览(99)
  • 微服务 SpringBoot 整合 Redis GEO 实现附近商户功能

    本文参考黑马 点评项目 在点评项目中 如何 实现 附近商家的查询呢,展示出距离自己5公里内的商户,这样的功能如何实现? 答案是可以采用Redis 来实现,当然可能有很多实现方式,本文主要介绍如何使用Redis实现 附近商户的搜索功能 CSDN博客之星参选博主:Bug终结者 我正在

    2024年01月16日
    浏览(48)
  • ISO13849功能安全从入门到精通(2):安全功能的设计和技术实现_iso13849讲解(2)

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新网络安全全套学习资料》

    2024年04月26日
    浏览(27)
  • Mysql的安装配置教程(非常详细)从零基础入门到精通,看完这一篇就够了

    首先简单概述分为几个步骤: 一、下载Mysql 二、安装Mysql 三、验证Mysql安装是否成功 四、 配置环境变量 五、验证配置环境变量是否成功 一、下载Mysql 要在Windows或Mac上安装MySQL,首先从MySQL官方网站下载最新的MySQL Community Server版本: 官网:https://www.mysql.com/ 1.首先进入官网页面

    2024年02月05日
    浏览(51)
  • 微信小程序使用高德地图实现检索定位附近周边的POI功能示例

           解压下载的文件得到 amap-wx.js ,在创建的项目中,新建一个名为 libs 目录,将 amap-wx.js 文件拷贝到 libs 的本地目录下。 登录微信公众平台,在 \\\"设置\\\" → \\\"开发设置\\\" 中设置 request 合法域名,将  https://restapi.amap.com  中添加进去,如下图所示:    

    2024年02月03日
    浏览(70)
  • ROS从入门到精通10-1:项目实战之智能跟随机器人原理与实现

    本专栏旨在通过对ROS的系统学习,掌握ROS底层基本分布式原理,并具有机器人建模和应用ROS进行实际项目的开发和调试的工程能力。 🚀详情:《ROS从入门到精通》 机器人是传感器网络、通信、人工智能、分布式计算、自动化等多种技术的集大成者, 机器人技术的发展水平标

    2024年02月07日
    浏览(47)
  • c#入门教程(有一定计算机基础的人看)

    废话不说,有一定基础的人看,如java等程序员 开发语言,为什么要学?主流游戏是用这个开发 c#微软做的,微软做了个.net framework,c#运行在这个之上。windows自带.net framework,但太辣鸡了,只支持windows,效果不好,就没更了,然后微软出了个新的 .net core ,支持linux,windows,m

    2024年02月04日
    浏览(105)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包