wake-up-neo.com

Welcher MySQL-Datentyp sollte für Latitude/Longitude mit 8 Dezimalstellen verwendet werden?

Ich arbeite mit Kartendaten und der Latitude/Longitude erweitert sich auf 8 Dezimalstellen. Zum Beispiel:

Latitude 40.71727401
Longitude -74.00898606

Ich sah im Google-Dokument Welches verwendet: 

lat FLOAT( 10, 6 ) NOT NULL,  
lng FLOAT( 10, 6 ) NOT NULL

ihre Dezimalstellen gehen jedoch nur auf 6.
Sollte ich FLOAT(10, 8) verwenden, oder gibt es eine andere Methode, um diese Daten zu speichern, so ist dies genau. Es wird bei Kartenberechnungen verwendet. Vielen Dank!

189
Edward

DECIMAL ist der MySQL-Datentyp für die exakte Arithmetik. Im Gegensatz zu FLOAT ist die Genauigkeit für jede Zahlengröße festgelegt. Wenn Sie also FLOAT anstelle von FLOAT verwenden, vermeiden Sie möglicherweise Präzisionsfehler bei einigen Berechnungen. Wenn Sie die Zahlen nur ohne Berechnung speichern und abrufen würden, wäre FLOAT in der Praxis sicher, obwohl die Verwendung von DECIMAL kein Schaden darstellt. Mit Berechnungen ist FLOAT meistens noch in Ordnung, aber um sicher zu sein, 8d.p. Präzision sollten Sie DECIMAL verwenden.

Breitengrade reichen von -90 bis +90 (Grad), also ist DECIMAL (10, 8) dafür in Ordnung, aber Längengrade reichen von -180 bis +180 (Grad), also benötigen Sie DECIMAL (11, 8). Die erste Zahl ist die Gesamtzahl der gespeicherten Ziffern und die zweite ist die Zahl nach dem Dezimalzeichen.

Kurz gesagt: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL

This erklärt, wie MySQL mit Fließkomma-Datentypen arbeitet.

475
gandaliter

Außerdem sehen Sie, dass die float-Werte gerundet sind.

 // z. B. gegebene Werte 41.0473112,29.0077011 

 float (11,7) | dezimal (11,7) 
 --------------------------- 
 41.0473099 | 41,0473112 
 29.0077019 | 29.0077011 

12
K-Gun

Sie können Ihren Datentyp als vorzeichenbehaftete Ganzzahl festlegen. Wenn Sie die Koordinaten für SQL speichern, können Sie lat * 10000000 und long * 10000000 festlegen. Wenn Sie mit Abstand/Radius auswählen, teilen Sie die Speicherkoordinaten in 10000000 auf. Ich habe es mit 300.000 Zeilen getestet, die Antwortzeit der Abfrage ist gut. (2 x 2,67 GHz-CPU, 2 GB RAM, MySQL 5.5.49)

6

Verwenden Sie kein Float ... Es werden Ihre Koordinaten gerundet, was zu seltsamen Vorkommnissen führt.

Verwenden Sie dezimal

2
Sam Sabey

in Laravel verwendet Dezimalspalte Typ für die Migration

$table->decimal('latitude', 10, 8);
$table->decimal('longitude', 11, 8);

weitere Informationen see verfügbarer Spaltentyp

2
Jignesh Joisar

Der beste Weg in meinem Fall war, die Koordinaten als DOUBLE zu speichern.

lat DOUBLE NOT NULL,  
lng DOUBLE NOT NULL

Der gesamte Wert wird ohne Rundung gespeichert.

Wenn Sie den Wert runden müssen, empfehle ich, dass diese Behandlung am Ursprung der Daten erfolgt, beispielsweise in der Benutzeroberfläche.

1
tioperez

MySQL unterstützt jetzt räumliche Datentypen, da diese Frage gestellt wurde. Die aktuell akzeptierte Antwort ist also nicht falsch. Wenn Sie jedoch nach zusätzlichen Funktionen wie dem Finden aller Punkte in einem bestimmten Polygon suchen, verwenden Sie den Datentyp POINT.

In den Mysql-Dokumenten zu Geodatentypen nachsehen und Funktionen zur räumlichen Analyse

1
Bill--

Verwenden Sie die Migration von Ruby on Rails

class CreateNeighborhoods < ActiveRecord::Migration[5.0]
  def change
    create_table :neighborhoods do |t|
      t.string :name
      t.decimal :latitude, precision: 15, scale: 13
      t.decimal :longitude, precision: 15, scale: 13
      t.references :country, foreign_key: true
      t.references :state, foreign_key: true
      t.references :city, foreign_key: true

      t.timestamps
    end
  end
end
0
gilcierweb

Ich glaube, der beste Weg, Lat/Lng in MySQL zu speichern, ist eine POINT-Spalte (2D-Datentyp) mit einem SPATIAL-Index.

CREATE TABLE `cities` (
  `Zip` varchar(8) NOT NULL,
  `country` varchar (2) GENERATED ALWAYS AS (SUBSTRING(`Zip`, 1, 2)) STORED,
  `city` varchar(30) NOT NULL,
  `centre` point NOT NULL,
  PRIMARY KEY (`Zip`),
  KEY `country` (`country`),
  KEY `city` (`city`),
  SPATIAL KEY `centre` (`centre`)
) ENGINE=InnoDB;


INSERT INTO `cities` (`Zip`, `city`, `centre`) VALUES
('CZ-10000', 'Prague', POINT(50.0755381, 14.4378005));
0
dayvee.cz