欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql使用Haversine 公式和ST_Distance_Sphere 函數(shù)實(shí)現(xiàn)附近的人功能

 更新時(shí)間:2023年08月25日 10:00:47   作者:水滴技術(shù)  
使用 MySQL 來實(shí)現(xiàn)“附近的人”功能,可以通過Haversine 公式和ST_Distance_Sphere 函數(shù)兩種方式來實(shí)現(xiàn),這篇文章主要介紹了mysql實(shí)現(xiàn)附近的人功能,需要的朋友可以參考下

對(duì)于“附近的人”功能,在生活中是比較常用的,像外賣app附近的美食,共享單車app里附近的車輛等等。我們之前使用 ElasticSearch 實(shí)現(xiàn)過該功能,本篇文章我們介紹如何通過 MySQL 來實(shí)現(xiàn)“附近的人”功能。

在這里插入圖片描述

ST_Distance_Sphere 函數(shù)

在 MySQL 中,ST_Distance_Sphere 函數(shù)是一個(gè)地理空間函數(shù),用于計(jì)算兩個(gè)地理位置之間的球面距離。它基于球體模型進(jìn)行計(jì)算,并返回兩個(gè)點(diǎn)之間的距離結(jié)果。

ST_Distance_Sphere 函數(shù)的語法如下:

ST_Distance_Sphere(point1, point2)

其中,point1point2 是表示地理位置的 POINT 類型的參數(shù)。

示例一:計(jì)算北京站到北京西站的距離

以下是一個(gè)使用 ST_Distance_Sphere 函數(shù)計(jì)算球面距離的示例:

-- 北京站 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 類型的參數(shù)表示兩個(gè)地理位置點(diǎn),分別是北京站(經(jīng)度 116.427322,緯度 39.902822)和北京西站(經(jīng)度 116.322083,緯度 39.8949)。然后,我們調(diào)用 ST_Distance_Sphere 函數(shù)來計(jì)算這兩個(gè)點(diǎn)之間的球面距離,并將結(jié)果命名為 distance。

返回結(jié)果:

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

ST_Distance_Sphere 函數(shù)的返回值是以米為單位的球面距離,可以根據(jù)需要將結(jié)果轉(zhuǎn)換為千米。上面示例中可以看出,北京站到北京西站的距離約為9公里。

需要注意的是,使用 ST_Distance_Sphere 函數(shù)進(jìn)行球面距離計(jì)算需要 MySQL 版本 8.0.17 或更高版本,并且需要在數(shù)據(jù)庫中啟用地理空間功能。

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

要實(shí)現(xiàn)"附近的人"功能,可以使用MySQL的ST_Distance_Sphere 函數(shù)和索引來處理地理位置數(shù)據(jù)。下面是一個(gè)基本的實(shí)現(xiàn)步驟:

(1)創(chuàng)建GEO測(cè)試表:其中包括id 主鍵、location地理位置信息。地理位置信息可以使用POINT類型來表示。

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

(2)添加地理位置數(shù)據(jù):向表中插入地理位置數(shù)據(jù)。

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)創(chuàng)建地理索引:為該表的地理位置字段創(chuàng)建索引,以便進(jìn)行空間查詢。

CREATE SPATIAL INDEX idx_location ON test_geo (location);

(4)查詢附近的人:使用地理空間函數(shù)進(jìn)行附近的人查詢。

  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 -- 兩公里內(nèi)
  ORDER BY
    distance -- 由近及遠(yuǎn)排序
  ; 

上述查詢使用了ST_Distance_Sphere函數(shù)來計(jì)算兩個(gè)地理位置之間的球面距離,POINT ( 116.410539, 39.912983 ) 是你的坐標(biāo),2000是查詢半徑。這個(gè)查詢將返回在給定半徑范圍內(nèi)的數(shù)據(jù)。

查詢結(jié)果:

在這里插入圖片描述

Haversine 公式

ST_Distance_Sphere 函數(shù)要求MySQL 的版本為 8.0.17 或更高,對(duì)于低版本的 MySQL 該怎么辦呢?我們可以使用 Haversine 公式來實(shí)現(xiàn)。

Haversine 是一種常用的球面三角函數(shù),用于計(jì)算兩個(gè)球面位置之間的球面距離。它是根據(jù)地球的球體模型進(jìn)行計(jì)算的,可以用于近似計(jì)算兩個(gè)經(jīng)緯度坐標(biāo)之間的球面距離。

Haversine 公式基于球面三角學(xué)和經(jīng)緯度之間的關(guān)系。它的公式如下:

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

其中:

  • lat1lat2 是兩個(gè)點(diǎn)的緯度(以弧度表示)。
  • lon1lon2 是兩個(gè)點(diǎn)的經(jīng)度(以弧度表示)。
  • Δlat 是緯度之差,即 lat2 - lat1。
  • Δlon 是經(jīng)度之差,即 lon2 - lon1。
  • R 是地球的半徑,常用的單位是千米或英里。

通過應(yīng)用 Haversine 公式,可以近似計(jì)算出兩個(gè)經(jīng)緯度坐標(biāo)之間的球面距離。這個(gè)公式考慮了球體的曲率,因此對(duì)于較短距離的計(jì)算具有較高的精度。然而,對(duì)于較長距離,特別是跨越大片陸地或海洋的距離,Haversine 公式可能會(huì)引入一定的誤差。

在使用 Haversine 公式進(jìn)行計(jì)算時(shí),需要注意輸入的經(jīng)緯度必須使用弧度表示。如果經(jīng)緯度是以度數(shù)表示,需要將其轉(zhuǎn)換為弧度形式進(jìn)行計(jì)算。

示例一:計(jì)算北京站到北京西站的距離

以下是一個(gè)使用Haversine公式計(jì)算球面距離的示例:

-- 北京站 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

在上述示例中,我們分別將北京站(經(jīng)度 116.427322,緯度 39.902822)和北京西站(經(jīng)度 116.322083,緯度 39.8949)的經(jīng)緯度數(shù)據(jù)帶入Haversine公式中,然后就可以計(jì)算出這兩個(gè)點(diǎn)之間的球面距離,并將結(jié)果命名為 distance。

返回結(jié)果:

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

Haversine公式的返回值是以千米為單位的球面距離。

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

我們可以使用Haversine公式來實(shí)現(xiàn)"附近的人"功能,下面是一個(gè)基本的實(shí)現(xiàn)步驟:

(1)創(chuàng)建GEO測(cè)試表:其中包括id 主鍵、地理位置信息。地理位置信息可以使用lng表示經(jīng)度,lat表示緯度。

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

(2)添加地理位置數(shù)據(jù):向表中插入地理位置數(shù)據(jù)。

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公式進(jìn)行附近的人查詢。

 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  -- 兩公里內(nèi)
ORDER BY
  distance -- 由近及遠(yuǎn)排序
;

上述查詢使用了Haversine公式來計(jì)算兩個(gè)地理位置之間的球面距離,116.410539, 39.912983 是你的坐標(biāo),2是查詢半徑。這個(gè)查詢將返回在給定半徑范圍內(nèi)的數(shù)據(jù)。

查詢結(jié)果:

在這里插入圖片描述

總結(jié)

使用 MySQL 來實(shí)現(xiàn)“附近的人”功能,可以通過Haversine 公式和ST_Distance_Sphere 函數(shù)兩種方式來實(shí)現(xiàn)。對(duì)于低版本的 MySQL 只能使用Haversine 公式,但我們還是推薦升級(jí)你的 MySQL(8.0.17版本或更新),因?yàn)槭褂?code>ST_Distance_Sphere 函數(shù)不僅使用簡單,而且它還支持空間索引,使得查詢速度更快。

到此這篇關(guān)于mysql實(shí)現(xiàn)附近的人功能的文章就介紹到這了,更多相關(guān)mysql附近的人內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 什么是blob,mysql blob大小配置介紹

    什么是blob,mysql blob大小配置介紹

    BLOB (binary large object),二進(jìn)制大對(duì)象,是一個(gè)可以存儲(chǔ)二進(jìn)制文件的容器。在計(jì)算機(jī)中,BLOB常常是數(shù)據(jù)庫中用來存儲(chǔ)二進(jìn)制文件的字段類型
    2012-02-02
  • win10下完全卸載+重裝MySQL步驟詳解

    win10下完全卸載+重裝MySQL步驟詳解

    小編是因?yàn)檫B接MySQL和Qt時(shí)出現(xiàn)問題,迫不得已選擇把64bitMySQL換成了32bitMySQL,在安裝過程中出現(xiàn)各種問題,下面小編把 win10下完全卸載+重裝MySQL步驟分享到腳本之家平臺(tái),需要的朋友參考下
    2017-12-12
  • Mysql中二進(jìn)制日志操作方法說明

    Mysql中二進(jìn)制日志操作方法說明

    這篇文章主要介紹了Mysql中二進(jìn)制日志操作方法,二進(jìn)制日志中以“事件”的形式記錄了數(shù)據(jù)庫中數(shù)據(jù)的變化情況,對(duì)于MySQL數(shù)據(jù)庫的災(zāi)難恢復(fù)起著重要的作用
    2023-03-03
  • Winserver2012下mysql 5.7解壓版(zip)配置安裝教程詳解

    Winserver2012下mysql 5.7解壓版(zip)配置安裝教程詳解

    這篇文章主要介紹了Winserver2012下mysql 5.7解壓版(zip)配置安裝教程詳解,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • MySQL建表設(shè)置默認(rèn)值的取值范圍

    MySQL建表設(shè)置默認(rèn)值的取值范圍

    這篇文章主要介紹了MySQL建表設(shè)置默認(rèn)值的取值范圍,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • MySql 8.0及對(duì)應(yīng)驅(qū)動(dòng)包匹配的注意點(diǎn)說明

    MySql 8.0及對(duì)應(yīng)驅(qū)動(dòng)包匹配的注意點(diǎn)說明

    這篇文章主要介紹了MySql 8.0及對(duì)應(yīng)驅(qū)動(dòng)包匹配的注意點(diǎn)說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Ubuntu系統(tǒng)安裝mysql超詳細(xì)步驟

    Ubuntu系統(tǒng)安裝mysql超詳細(xì)步驟

    這篇文章主要給大家介紹了關(guān)于Ubuntu系統(tǒng)安裝mysql的相關(guān)資料,現(xiàn)在的軟件越來越好安裝,尤其是在ubuntu下安裝軟件,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-09-09
  • MySQL的主從復(fù)制步驟詳解及常見錯(cuò)誤解決方法

    MySQL的主從復(fù)制步驟詳解及常見錯(cuò)誤解決方法

    這篇文章主要介紹了MySQL的主從復(fù)制步驟詳解及常見錯(cuò)誤解決方法,文中主張同步時(shí)跳過臨時(shí)錯(cuò)誤,并對(duì)Slave_IO_Running: No錯(cuò)誤的解決給出了方案,需要的朋友可以參考下
    2016-02-02
  • 詳解MySQL數(shù)據(jù)庫的安裝與密碼配置

    詳解MySQL數(shù)據(jù)庫的安裝與密碼配置

    本文主要對(duì)MySQL數(shù)據(jù)庫的安裝與密碼配置進(jìn)行詳細(xì)介紹,具有一定的參考價(jià)值。下面就跟小編一起來看下吧
    2016-12-12
  • MySQL文件權(quán)限存在的安全問題和解決方案

    MySQL文件權(quán)限存在的安全問題和解決方案

    MySQL文件權(quán)限是用來控制用戶對(duì)數(shù)據(jù)庫文件以及目錄的操作權(quán)限,在MySQL中,這些權(quán)限通常由系統(tǒng)管理員分配,通過GRANT和REVOKE語句進(jìn)行管理,本文給大家介紹了MySQL文件權(quán)限存在的安全問題和解決方案,需要的朋友可以參考下
    2024-07-07

最新評(píng)論