はじめに
数値を丸められること無く、記録したとおりに緯度経度情報を保存したい。
もちろん文字列型ではなく浮動小数点型を使う方が処理効率が良いですよね。
どのようなカラムを使えば意図通りに保存出来るのかまとめてみました。
結論
VARCHAR型やDECIMAL型を利用する手もありますが、どちらも計算コストが高いため、
基本的にdouble(9,6)
を利用すれば問題ないでしょう。
最大値と最小値
それぞれの最小値と最大値は次の通りです。
- 緯度 (latitude) : -90 〜 90
- 経度 (longitude) : -180 〜 180
小数点桁数と精度の関係
どの程度の精度を求めるには、どの程度の桁数が必要となるか、まとめてみましょう。
ざっくりと計算しますと地球の円周は約40,000,000mで
緯度はぐるっと360度ですから緯度1度は40000000/360≒111111.1111...
で約111,111mになります。
経度緯度のDBカラムの桁数 【OKWave】
http://okwave.jp/qa/q4506558.html
こちらを表にすると、次の通りです。5〜6桁もあれば日常のユースケースに対応出来そうですね。
小数点以下桁数 | 緯度 | 概算距離 | MySQLのカラム型 (緯度/lat) | MySQLのカラム型 (経度/lng) |
---|---|---|---|---|
0 | 1度 | 111km | double(2,0) | double(3,0) |
1 | 0.1度 | 11km | double(3,1) | double(4,1) |
2 | 0.01度 | 1111m | double(4,2) | double(5,2) |
3 | 0.001度 | 111m | double(5,3) | double(6,3) |
4 | 0.0001度 | 11m | double(6,4) | double(7,4) |
5 | 0.00001度 | 1m | double(7,5) | double(8,5) |
6 | 0.000001度 | 11cm | double(8,6) | double(9,6) |
7 | 0.0000001度 | 1cm | double(9,7) | double(10,7) |
カラムの引数は double(桁数, 小数点以下の桁数)
という指定となっています。
スキーマ例
緯度経度を格納するテーブルのスキーマ例は次の通りです。
ただ、緯度経度それぞれの型を共通化しておきたい場合には、大きい方のdouble(9,6)
に合わせると良いでしょう。
CREATE TABLE `geo_locations` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`lat` double(8,6) DEFAULT NULL,
`lng` double(9,6) DEFAULT NULL
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
さらに空間情報インデックス(geometory index)を付与して検索する際には、次のようにスキーマをセットします。
MySQL 5.7からは対応していますが、それ以前のバージョンではInnoDBはSPATIALインデックス非対応です。
そのため、MySQL 5.0/5.1/5.5/5.6環境で高速に検索できるようにする場合には、次のようにスキーマをセットする必要があります。
CREATE TABLE `geo_locations` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`location` geometry NOT NULL, -- NOT NULLである必要があります
PRIMARY KEY (`id`),
SPATIAL KEY `geo_location` (`location`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
バージョン問わずInnoDBで緯度経度検索を高速に行う場合は、B-Treeインデックスの使えるGeoHash形式を使うと良いです。
http://d.hatena.ne.jp/hiratara/20100824/1282635611
あわせて読みたい
-
緯度経度1度の距離 - モノノフ日記
http://mononofu.hatenablog.com/entry/20090324/1237894846 -
MySQL TIPS 3 空間情報(geometry)を使って経度・緯度の検索を高速化する
http://d.hatena.ne.jp/IT7C/20100723/1279835242