web-dev-qa-db-ja.com

小数点以下8桁の緯度/経度に使用するMySQLデータ型は何ですか?

私は地図データを扱っています、そしてLatitude/Longitudeは小数点以下8桁まで拡張されています。例えば:

Latitude 40.71727401
Longitude -74.00898606

私は Googleドキュメント を見ました:

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

ただし、小数位は6になります。
私はFLOAT(10, 8)を使うべきですか、それとも正確なのでこのデータを保存するために考慮すべき別の方法がありますか。これはマップ計算で使用されます。ありがとうございます。

206
Edward

DECIMALは正確な算術演算のためのMySQLデータ型です。 FLOATとは異なり、精度は任意のサイズの数値に対して固定されているため、FLOATの代わりにそれを使用すると、計算を行うときに精度エラーを回避できます。計算せずに数値を格納して取り出すだけなら、実際にはFLOATが安全ですが、DECIMALを使用しても問題ありません。計算ではFLOATはまだ大体問題ありませんが、8d.pを絶対に確実にするためです。精度はDECIMALを使用してください。

緯度は-90〜+ 90(度)の範囲であるため、DECIMAL(10、8)で問題ありませんが、経度は-180〜+ 180(度)の範囲であるため、DECIMAL(11、8)が必要です。最初の数字は保存されている桁数の合計です。2番目の数字は小数点の後の数字です。

一言で言えば:lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL

This MySQLがどのように浮動小数点データ型を扱うかを説明します。

505
gandaliter

さらに、floatの値が丸められているのがわかります。

 //例:与えられた値41.0473112、29.0077011 
 
 float(11,7)| decimal(11,7)
 --------------------------- 
 41.0473099 | 41.0473112 
 29.0077019 | 29.0077011 
 
14
K-Gun

データ型を符号付き整数として設定できます。 SQLへの格納座標は、lat * 10000000とlong * 10000000として設定できます。また、距離/半径で選択すると、格納座標を10000000に分割します。300K行でテストしたところ、クエリの応答時間は良好です。 (2 x 2.67GHz CPU、2 GB RAM、MySQL 5.5.49)

6

Floatを使用しないでください。座標が丸められて、奇妙なことが起こります。

10進数を使用

3
Sam Sabey

laravelでマイグレーションに使用される10進数列タイプ

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

詳細については 参照 available column type

2
Jignesh Joisar

私の場合の最良の方法はDOUBLEとして座標を保存することでした。

lat DOUBLE NOT NULL,  
lng DOUBLE NOT NULL

丸めずに値全体を保存します。

値を四捨五入する必要がある場合は、この処理はデータの原点、たとえばUIで行われることをお勧めします。

1
tioperez

この質問がされて以来、MySQLは空間データ型をサポートしています。したがって、現在受け入れられている答えは間違っていませんが、特定の多角形内のすべての点を見つけるなどの追加機能を探している場合は、POINTデータ型を使用します。

地理データ型に関するMysql Docsをチェックアウト そして 空間分析関数

1
Bill--

Migrate 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

MySQLにLat/Lngを保存する最良の方法は、SPATIALインデックスを持つPOINT列(2Dデータ型)を持つことだと思います。

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