Linuxな環境にPostGISをインストールする

2009/08/31 | PostgreSQL

これまではお試しということでWindowsで試していたが、本格的にLinuxで構築することになった(別にWindowsはオチャラケでLinuxがマジメという意味ではない)。Windowsではインストーラから簡単にpostgreSQLからPostGISまでインストールできるけど、Linuxではそうは簡単にいかない(とわかってはいたのだが・・・)。

今回のディストリビューションはCentOS5。最近はネットワーク関係の仕事は一切していなかったので、OSなんて気にも留めていなかったのだが、Ubuntuとかいろいろなディストリビューションがあるらしい(名前は聞いていたけど、ぜんぜん興味なし)。まぁ、CentOS5は一般的だし、RedHatの正統な流れだし(いや、正統なのはRedHatなわけだが)、契約したサーバがCentOS5だったし、CentOS5が使えるサーバが多いし、慣れ親しんでいるし・・・。他のOS使ったことないから、もっぱらCentOSなだけなんだけど。

まず調べたが、当然のごとくデフォルトのyumリポジトリにはPostGISは存在しない。よって必然的にサードパーティー。ウェブでいろいろ検索してみたら「試験管のなかのコード」さんの記事でCentOS5とPostgreSQLのインストール記事があり、そちらでサードパーティーからのPostgreSQLインストールが紹介されていた。そこにpostgisの文字が!。しかもyumで管理できるみたいだし「こりゃいいや」と思ってやってみたけど、どうもうまくいってくれなかった。

で、結局rpmfindを使うことに。yum管理ではなくなるのでちょっと微妙だけど、背に腹は代えられないのでまずはrpm探しをしてみることにした。そしたらありました。

postgis-1.2.1-1.el5.rf.i386.rpm
postgis-utils-1.2.1-1.el5.rf.i386.rpm

とりあえずpostgis本体をインストールしようとしたけどエラー。proj-develというのとgeos-develがないと怒っている。もう後は依存関係を解消すべく、ひたすら検索。そうすると合計4点インストールすることになった。

geos-3.1.0-1.el5.rf.i386.rpm
geos-devel-3.1.0-1.el5.rf.i386.rpm
proj-4.5.0-3.el5.i386.rpm
proj-devel-4.5.0-3.el5.i386.rpm

いちおうインストールを完了し、それからpostgisをインストールしようとコマンド一発!・・・できたぁーっ。rpmfindに感謝。しかしこの時点ではpostgis-utilsがインストールできていない。ユーティリティだから、なくても問題ないとは思うが、ちょっと気になる。

perl(Pg) is needed

と言われているだが、これは何。rpmfindでperl-Pgというのがあるみたいだが、ここにはRedHat用が見当たらないから、インストールしたくない。ということで放置することにする。

さて、これでPostGISが使えるようになったかどうかはわからない。PostgreSQLを初期化してみればわかることだけど、まだPostgreSQLは起動さえしていないからだ。あとでゆっくりチェックしてみることにする。

PostGISなテーブルにデータをINSERT

2009/08/02 | PostgreSQL

とりあえず、なんとなくPostGISの使い方がわかってきたので、PostGISなテーブルにデータを挿入する方法をメモしておく。

INSERT INTO [テーブル名]
([カラム名])
VALUES
(
GeomFromText(‘POINT([経度] [緯度])’,[座標系])
);

座標系はSRIDってやつなので、WGS84の場合は4326になる。経度と緯度は度分秒ではなく度であらわし、分秒は度の小数として指定(Google Mapsと同じ)。POINTってのはポイントってこと(当たり前)。というか、これも関数。多分挿入するカラムと同じである必要があると思う。他にも型に合わせてLINESTRINGとかPOLYGONとかあるみたい。当面はPOINTだけ知っていればよさそう。

PostGISなカラムにインデックス

2009/08/01 | PostgreSQL

PostGISを使って空間座標を格納するカラムをテーブルに追加する際は、create文で一気に作るのではなく(本当は一気に作ることもできるだろうが)、最初に空間座標以外のカラムでテーブルをつくり、あとからPostGISの関数を使って空間座標カラムを追加する。専用の関数を使うのだから、それだけで事足りているのだろうと思っていたら、別途インデックスを作成することもできるようだ(言い方をかえると、別途作成しなくてはいけない)。

PostGISのマニュアルではこんな具合に書いてある。
CREATE INDEX [インデクス名] ON [テーブル名] USING GIST ( [ジオメトリカラム名] );

でもウェブを調べると、カラム名の後ろに半角スペースをつけて「GIST_GEOMETRY_OPS」というおまじないをつけてあることが多い。これの意味を調べたけど、今のところよくわからない。もうちょっと調べなくては。

インデックスを作成した後は、PostgreSQLがうまくインデックスを使ってくれるようにバキュームをかけておかなくてはいけないらしい(統計情報収集)。こういうことを知らなかったので、今までいかに何も考えずにデータベースを使っていたのかがばれてしまう。

VACUUM ANALYZE [テーブル名] [カラム名];

これで空間座標のカラムにインデックスが効いて、位置検索するときに速度向上が見込める(らしい)。数千行以上のデータを扱う際は入れておくべき、とのこと。

MySQLの照会順序(やっぱutf8_general_ciかな)

2009/07/28 | MySQL

機能のメモをしていて調べてみると、いろんな意見があった。記述忘れもあったのでメモしてみる。utf8_general_ciとutf8_unicode_ciの違いの続き。

まずutf8_general_ciのほうが高速と書いてあるサイトもある。正確かどうかというのは「何を持って正確とするか」という定義に依存するだろうから議論しないけれど・・・、どっちが速いんだろう。好みの動作という点ではutf_general_ciなんだけど。

utf8_unicode_ciでもう一つ。「は」「ぱ」「ば」「ハ」「パ」「バ」なんてのも全部同一視するらしい。ゆるい。こういうのを同一視しようと思ったらそれなりに大変なような気がするから、こっちのほうが速度が遅いような気もするな。

んー。あとSET NAMESの設定とか、なんか、いろいろ考えたら、もうちょっとデータベースのことや文字コードのことをしっかり勉強しなきゃいけないなぁと痛感する今日この頃だ。こういうことを勉強してくれる立派な家来をみつけなくては(他力本願)。

MySQLの照会順序

2009/07/27 | MySQL

基本的に今は文字コードを全てUTF-8で統一するようにしている。もともとPHPはシフトJISが得意でないし、いまさらEUC-JPを使う理由もない。自分のウェブサイトを構築する場合は、携帯サイトを除いて出力もUTF-8だ(ウェブサービスとの親和性もいいし)。必然的にデータベースもUTF-8でデータを格納しているわけなんだが。

MySQLでいつも迷う点がある。いわゆる照会順序ってやつ。SQL serverなんかでは照合順序って名前になってることもある。照会順序とは「言語種別」と「ロケール」に基づく文字列の比較方法の規則のこと(らしい)。文字列の比較だからWHERE句での比較はもちろんだし、ORDER句の並び替えにも影響するので、希望通りの結果を得たい場合はしっかり設定しておかないといけない。でも、これ、いろいろあるんだな。

文字列に対しての影響を及ぼすわけだから、数値型カラムなどは関係ない。varchar型やtext型で設定しなくてはいけない(つまりカラムごとにも設定できるっぽい)。それにデータベースのデフォルト照会順序も設定できるし、テーブルでも照会順序を設定できる。照会順序で設定できる値は大量にあるのだが、日本語環境でUTF-8を使っている場合に設定するであろう値は以下の3つだ。

  • utf8_bin
  • utf8_general_ci
  • utf8_unicode_ci

最初のはbin。これはバイナリ(binary)レベルで検査してくれる。バイナリで見てくれるわけだから、絶対確実。間違いなく期待通りの答えを返してくれそうな感じ。

あとの2つは両方とも後ろに_ciとなっているが、これは「case insensitive」の略。つまり大文字小文字(upper caseとlower case)を区別しない(「sensitive:敏感」でない)という意味だ。だからバイナリレベルでのチェックではないことは明らか。これだけ見ればbinがいいような気がするけれど、マルチバイトもシングルバイトも関係なくてバイトオーダーで検査するので、ひょっとしたら希望通りの動作にならないことがあるかもしれない。

で_ciな二つだが、前者(general)は英数の全角半角の判断くらいはしてくれるらしい(大文字小文字は判断しない)のに対して、後者(unicode)は全角半角大文字小文字も判断しないらしい。例えば文字列比較で以下のような例を考える。

  1. (半角大文字のA)=(全角大文字のA)
  2. (半角大文字のA)=(半角小文字のa)

前者(general)だと1はfalse、2はtrueだが、後者(unicode)だた1もtrue、2もtrueになる。どんな動きをしてほしいかということは、用途によってそれぞれだから一概にどちらが正しいとは言えないけれど、ちょっとややこしい。でも、前者のほうがなんとなく正確っぽいので、より厳密なのかなと思う。後者はなんとなくあいまいっぽいので、処理が簡単そう。だから正確度ならgeneral、速度ならunicodeということになるだろうか。

用途によるんだけど、まぁ、どれを使っても、一般人の考えているとおりの動作はしてくれなさそうだ。がんばって使い分けるしかない。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net