Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
167
Help us understand the problem. What is going on with this article?

More than 5 years have passed since last update.

@y-ken

MySQLに緯度経度を保存する際の、カラム型の選び方

はじめに

数値を丸められること無く、記録したとおりに緯度経度情報を保存したい。
もちろん文字列型ではなく浮動小数点型を使う方が処理効率が良いですよね。
どのようなカラムを使えば意図通りに保存出来るのかまとめてみました。

結論

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

あわせて読みたい

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
167
Help us understand the problem. What is going on with this article?