1つのファイルを1つのデータベースとして扱うPosqlを使ってみた

手軽でSQLが使えるストレージを探していて引っかかったPosqlを使ってみました。使ってみたのは、Version 2.08。

特徴としては、以下
-PHP単体で動作するライブラリ系のDBMS
-ファイル単位でデータベースを管理できる

元ネタ

SourceForge:http
: //sourceforgh.jp/projects/posql/

オフィシャル:http
: //feel.happy.nu/tool.php?tool_id=8&page=Posql

いいところ

使ってみた感想としては、馴染み深いPEARMDB2を経由して使えるのであまり深いことは考えなくても移行できた感じです。実際プログラム自体は、MDB2経由のMysqlだったときと比べて書き換えはほぼ無しでした。

また後述するようなSQLを使わなければ、Mysqlで使っていたSQLがほぼ無修正で動いたり、MysqlダンプしたSQLがほぼ無修正でインポートできたりといい感じです。いくつかの関数に対応していなかったり、Insert文でValuesを続けて書く書式に対応していなかったりしますが、少なくともMysqlPostgresql間よりはストレス無く移行できます。

ちなみに、MDB2からPosqlにアクセスするには、展開したPosqlディレクトリ内のPEAR以下を適当な場所に展開して、dnsを以下のように設定します。ファイルがある場合には、予めパーミッションを出しておくのを忘れずに。該当するファイルが無かった場合には、自動的に生成されますので、ディレクトリのパーミッションを出しておかないといけません。

|php|
$dsn = array(
'database' => '{対象となるDBファイル}',
'phptype' => 'posql',
);

||<

あと、デフォルトで「posqladmin.php」というPhpMyAdminと同じようなWebから管理できる仕組みがついてきます。機能は限定的ですが、ちょっとSQLを確認したり、データを見たりするのには十分ではないかと。

いくつか思うこと

使ってみていくつか思うことがあったので、以下。

動作速度について

ただし、流石にファイルを使ったIOを行っている都合か動作についてはかなり遅めかもしれません。MysqlダンプしたSQLを流し込むのにも、意外と時間がかかりました。

SQLのSELECT句について

SELECT句あたりにちょっと制限とバグ?があって、そのまま使うと意外と面倒かもしれません。

たとえば、以下のようなSQLだとエラーになります。
どうやら、「tablenamh.fieldname」と言う書式はサポートされていないようです。

|sql|
SELECT tablenamh.fieldname
FROM tablename
||<

あとSQLリファレンスではサポートされているはずなのですが、「tablenamh.*」と言う書式で書くとエラーになります。

|sql|
SELECT tablenamh.*
FROM tablename
||<

どうやら、SQLを解析した際の条件判定で「*」が以下のように文字チェックの対象から外れているようです。

|php|
at file posql.php, line 5757.

/*
* Checks whether the character string is a word
* equal to RegExp: [a-zA-Z_\x7F-\xFF]
*
* @param string a character string of target
* @return boolean whether string was word or not
* @access public
* @static
/
function isWord($char){
$ord = ord($char);

// ここの判定のところで「*」が文字扱いされていなくてエラーになる
return $ord === 0x5F || $ord > 0x7E
|| ($ord > 0x40 && $ord < 0x5B)
|| ($ord > 0x60 && $ord < 0x7B);
}

||<

ので、こういう風に変更するとエラーは出なくなりましたが、ホントにそれでいいのかは謎です

|php|
at file posql.php, line 5757.

/*
* Checks whether the character string is a word
* equal to RegExp: [a-zA-Z_\x7F-\xFF]
*
* @param string a character string of target
* @return boolean whether string was word or not
* @access public
* @static
/
function isWord($char){
$ord = ord($char);

// ここの判定のところで「*」が文字扱いする
return $ord === 0x5F || $ord > 0x7E || $ord === 0x2A
|| ($ord > 0x40 && $ord < 0x5B)
|| ($ord > 0x60 && $ord < 0x7B);
}

||<

SQLのALTERについて

レファレンスを見ている限りではALTERを使ってテーブルやフィールドの定義を変えることができません。

多分この辺はSqliteと同じように適当に入れれば適当にできるのかもしれません。試してないのでよくわかりませんが。

そのほか

現時点ではエクスポート機能がないため、なんらかの理由でDBMSを切り替えようとした場合には、自力でエクスポートしないといけません。これができれば、初めはposqlでお手軽に開発しておいて、速度やスケールが必要になったら他のDBMSに乗り換えるなんて使い方も現実味があるんですが、今のところはありません。

まとめ

ちょっとしたPHPのプロジェクトでDBMSを入れるまでも無いけど、CSVなんか使いたくないなぁっという場合にいいかもしれません。あと元々DBMSが使えないレンタルサーバなんかでもSQLが使えるようになるのはメリットかなぁ。

また、小規模開発時にはPosqlで開発しておいて、必要に応じて他のDBMSに移行できればいい感じかもしれません。前述しましたSQLに絡む問題もPosqlに合わせて開発時に気をつけておけば、他のDBMSに移行しても問題にはならないかと。

逆にMysqlなんかで開発していたものをPosqlに移行すると若干の調整が必要になってくるかもしれません。