Heim > Backend-Entwicklung > Python-Tutorial > Detaillierte Einführung der MySQL-Funktion für die Geoverarbeitung von geografischen Standorten (mit Code)

Detaillierte Einführung der MySQL-Funktion für die Geoverarbeitung von geografischen Standorten (mit Code)

不言
Freigeben: 2019-03-14 11:20:13
nach vorne
3104 Leute haben es durchsucht

Dieser Artikel bietet Ihnen eine detaillierte Einführung in die MySQL-Funktion zur Geoverarbeitung (mit Code). Ich hoffe, dass er Ihnen als Referenz dienen wird.

Derzeit basieren immer mehr Unternehmen auf LBS, Personen in der Nähe, Take-out-Standorten, Geschäften in der Nähe usw. Jetzt werden wir die Lösung für das Geschäftsszenario besprechen, das mir am nächsten kommt.

Derzeit bekannte Lösungen sind:

Berechnung benutzerdefinierter MySQL-Funktionen, MySQL-Geo-Index, Mongodb-Geo-Index, Postgresql, PostGis-Index, Redis, GeoElasticSearch

Dieser Artikel testet die Leistung der MySQL-Funktionsoperation

Vorbereitungsarbeiten

Datentabelle erstellen

CREATE TABLE `driver` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `lng` float DEFAULT NULL,
  `lat` float DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Nach dem Login kopieren

Testdaten erstellen

Verstehen Sie grundlegende geografische Kenntnisse, bevor Sie Daten erstellen:

  • Der Wertebereich des globalen Längengrads und Breitengrad ist: Breitengrad -90~90, Längengrad -180~180
  • Chinas Längen- und Breitengradbereich beträgt ungefähr: Breitengrad 3,86~53,55, Längengrad 73,66~135,05
  • Der Breitengrad des Verwaltungszentrums von Peking beträgt 39,92 und der Längengrad 116,46
  • Je weiter nördlich, desto größer der Breitengradwert, je weiter östlich, desto größer der Längengradwert
  • Grad und Minute Umrechnung: Grad- und Minuteneinheitsdaten in Gradeinheitsdaten umwandeln, Formel: Grad = Grad + Minute/60
  • Minuten- und Sekundenumrechnung: Grad-, Minuten- und Sekundeneinheitsdaten in Gradeinheitsdaten umwandeln, Formel: Grad = Grad + Minute / 60 + Sekunden / 60 / 60

Bei gleichem Breitengrad:

  • Der Längengrad beträgt alle 0,00001 Grad, der Abstand unterscheidet sich um etwa 1 Meter

Wenn die Längengrade gleich sind:

  • Der Breitengrad beträgt alle 0,00001 Grad und der Abstand unterscheidet sich um etwa 1,1 Meter

MySQL-Funktionsberechnung

DELIMITER //
CREATE DEFINER=`root`@`localhost` FUNCTION `getDistance`(
    `lng1` float(10,7) 
    ,
    `lat1` float(10,7)
    ,
    `lng2` float(10,7) 
    ,
    `lat2` float(10,7)

) RETURNS double
    COMMENT '计算2坐标点距离'
BEGIN
    declare d double;
    declare radius int;
    set radius = 6371000; #假设地球为正球形,直径为6371000米
    set d = (2*ATAN2(SQRT(SIN((lat1-lat2)*PI()/180/2)   
        *SIN((lat1-lat2)*PI()/180/2)+   
        COS(lat2*PI()/180)*COS(lat1*PI()/180)   
        *SIN((lng1-lng2)*PI()/180/2)   
        *SIN((lng1-lng2)*PI()/180/2)),   
        SQRT(1-SIN((lat1-lat2)*PI()/180/2)   
        *SIN((lat1-lat2)*PI()/180/2)   
        +COS(lat2*PI()/180)*COS(lat1*PI()/180)   
        *SIN((lng1-lng2)*PI()/180/2)   
        *SIN((lng1-lng2)*PI()/180/2))))*radius;
    return d;
END//
DELIMITER ;
Nach dem Login kopieren

Daten-Python-Skript erstellen

# coding=utf-8
from orator import DatabaseManager, Model
import logging
import random
import threading

""" 中国的经纬度范围 纬度3.86~53.55,经度73.66~135.05。大概0.00001度差距1米 """

# 创建 日志 对象
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

# Connect to the database

config = {
    'mysql': {
        'driver': 'mysql',
        'host': 'localhost',
        'database': 'dbtest',
        'user': 'root',
        'password': '',
        'prefix': ''
    }
}

db = DatabaseManager(config)
Model.set_connection_resolver(db)


class Driver(Model):
    __table__ = 'driver'
    __timestamps__ = False
    pass


def ins_driver(thread_name,nums):
    logger.info('开启线程%s' % thread_name)
    for _ in range(nums):
        lng = '%.5f' % random.uniform(73.66, 135.05)
        lat = '%.5f' % random.uniform(3.86, 53.55)

        driver = Driver()
        driver.lng = lng
        driver.lat = lat
        driver.save()

thread_nums = 10
for i in range(thread_nums):
    t = threading.Thread(target=ins_driver, args=(i, 400000))
    t.start()
Nach dem Login kopieren

Detaillierte Einführung der MySQL-Funktion für die Geoverarbeitung von geografischen Standorten (mit Code)

Das obige Skript erstellt 10 Threads und 10 Threads fügen 40.000 Daten ein. Die Ausführung dauerte 150,18 Sekunden und es wurden insgesamt 400.000 Datenelemente eingefügt

Test

  • Testumgebung

System: Mac OS

Speicher: 16G

CPU: Intel Core i5

Festplatte: 500g Solid State Drive

Finden Sie im Rahmen des Tests die 10 Treiber, die dem Koordinatenpunkt am nächsten liegen (134.38753,18.56734)

select *,`getDistance`(134.38753,18.56734,`lng`,`lat`) as dis from driver ORDER BY dis limit 10
Nach dem Login kopieren
  • Zeitaufwändig: 18,0 Sekunden
  • Erklärung: Vollständiger Tabellenscan

Ich habe das Intervall von 10.000 bis 100.000 mal 10.000 getestet und von 100.000 auf 90 Änderungen der Ergebnisse alle 100.000 Tests

Detaillierte Einführung der MySQL-Funktion für die Geoverarbeitung von geografischen Standorten (mit Code)

Fazit

  • Diese Lösung benötigt mehr als eine Abfrage, wenn das Datenvolumen 30.000 erreicht Sekunden
  • Ungefähr alle 10.000 zusätzlichen Einträge erhöht sich der Zeitverbrauch um 0,4 Sekunden

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung der MySQL-Funktion für die Geoverarbeitung von geografischen Standorten (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage