はじめに
MySQL8.0では位置情報に関する機能が充実した...という情報を見かけたので、試しにGeometry型というデータ型を使って、位置情報を格納するテーブルを作ってみることにしました。
※GIS関連は全く詳しくないので、誤りがありましたらご指摘頂けると幸いです。
使用した環境
- OS
- CentOS7.7(1908)
- RDBMS
- MySQL8.0.19
テーブルの作成
- 駅の位置を表す
station
というテーブルをnkojima
データベース内に作成しました。 - 位置情報は
location
というGeometry型のカラムに持たせています。 - 位置情報を表すデータ型はGeometry以外にも幾つか用意されており、以下に示したものは「OpenGIS クラスに対応するデータ型」となっています。
- POINT:地点を表す。
- LINESTRING:地点間を直線で結んだ線分を表す。
- POLYGON:多辺の幾何図形を表す。
- GEOMETRY:POINT、LINESTRING、POLYGONのいずれにも対応するルートクラス。
テーブルの作成
-- 駅情報テーブルの作成。
CREATE TABLE `nkojima`.`station` (
`id` INT AUTO_INCREMENT comment '駅ID',
`name` VARCHAR(50) NOT NULL comment '駅名',
`location` GEOMETRY NOT NULL comment '駅の座標',
`note` VARCHAR(200) comment '備考',
PRIMARY KEY (id),
INDEX name_idx(name)
)
ENGINE = InnoDB,
default charset=utf8mb4
comment='駅情報';
データの登録
- 都内のJRの駅から主要なものを選んで、大まかな座標を国土地理院の地図で取得しました。
- Geometry型として利用するにはSRID(空間参照系識別子)が必要になりますが、ここでは4326(WGS84)にセットしました。
- MySQL5.7では
GeomFromText
関数が使われていましたが、MySQL8.0以降はGeomFromText
関数は非推奨となっているため、ST_GeomFromText
を使うことになります。 -
GeomFromText
という名称はおそらく「Geometry From Text」の略で、「テキストからGeometry型に変換する」という処理がそのまま名称になっているのだと思われます。
INSERT文
USE nkojima;
INSERT INTO station (name, location, note) VALUES
("東京", ST_GeomFromText('POINT(35.681300 139.767165)', 4326), "23区"),
("新橋", ST_GeomFromText('POINT(35.666471 139.758357)', 4326), "23区"),
("品川", ST_GeomFromText('POINT(35.628829 139.739141)', 4326), "23区"),
("大崎", ST_GeomFromText('POINT(35.619131 139.728563)', 4326), "23区"),
("渋谷", ST_GeomFromText('POINT(35.658177 139.701741)', 4326), "23区"),
("新宿", ST_GeomFromText('POINT(35.688803 139.700925)', 4326), "23区"),
("池袋", ST_GeomFromText('POINT(35.730114 139.711053)', 4326), "23区"),
("日暮里", ST_GeomFromText('POINT(35.728163 139.770598)', 4326), "23区"),
("上野", ST_GeomFromText('POINT(35.713756 139.776950)', 4326), "23区"),
("四ツ谷", ST_GeomFromText('POINT(35.684834 139.730204)', 4326), "23区"),
("三鷹", ST_GeomFromText('POINT(35.702727 139.560978)', 4326), "多摩地区"),
("立川", ST_GeomFromText('POINT(35.698170 139.413671)', 4326), "多摩地区"),
("八王子", ST_GeomFromText('POINT(35.655370 139.339921)', 4326), "多摩地区"),
("北千住", ST_GeomFromText('POINT(35.749612 139.805059)', 4326), "23区"),
("赤羽", ST_GeomFromText('POINT(35.777732 139.721031)', 4326), "23区"),
("蒲田", ST_GeomFromText('POINT(35.562491 139.715924)', 4326), "23区");
データの検索
-
ST_AsText
関数を使うことで、Geometry型のカラムを人が見て理解できる形式で取得できます。 -
ST_AsText
関数を使わないと、Geometry型のカラムは16進数のデータとして表示されます。
mysql> SELECT
-> name AS 駅名,
-> ST_AsText(location) AS 緯度経度
-> FROM station
-> WHERE note='多摩地区';
+-----------+-----------------------------+
| 駅名 | 緯度経度 |
+-----------+-----------------------------+
| 三鷹 | POINT(35.702727 139.560978) |
| 立川 | POINT(35.69817 139.413671) |
| 八王子 | POINT(35.65537 139.339921) |
+-----------+-----------------------------+
まとめ
- ここまでの内容だとGeometry型などのデータ型を使うメリットがほとんど感じられませんが、「地点間の距離を計測する」「最寄りの地点を調べる」などの処理で力を発揮してくれるそうです。
- この辺りについては次に投稿する記事で触れたいと思います。