SQLiteをMovable Typeで使ってみる
「Movable Typeのマイナー機能を使ってみる」シリーズ第二弾。第一弾は「Ogawa::Memoranda: mt-view.cgiを使ってみる」。
あまり知られていないことですが、MT3.1の「テンプレートごとに管理可能なダイナミックPHPページ生成」機能はBerkeleyDBでは動作しません。3.1でこの機能を使いたい人はMySQLかPostgreSQLかSQLiteにとっとと移行する必要があります。
このうち、MySQL、PostgreSQLは三層Webアプリケーション構築においてはごくメジャー(かつ安価)なソリューションである一方、計算機に親しみ切れていない人々にとっては取っ付きの悪いのも事実です。そこで考えてみたいのは、やはりSQLiteっていうのは何なのかということです。
PHP5に標準でバンドルされるようになったのでご存知の方も多いとは思いますが、SQLiteはデータベースサーバではありません。構造データの操作をSQL言語で行うためのユーザーレベルライブラリです。MySQLのようなクライアント・サーバー型のDBサーバとは異なり、別のサーバプロセスを起動したり設定したりする必要もないため、非常にお手軽です。自分のソフトウェアにDB機能を組み込んで配布するのにも向いています。例えば、POPFile(POPFile - Automatic Email Classification)などにもSQLiteが組み込まれています。
また、SQLiteではデータベース単位に一個のイメージファイルが作成されます。テーブル単位でファイルが複数作られるBerkeleyDBや、dumpに少しワザ(Ogawa::Memoranda: LolipopのMySQLデータベースを簡単バックアップするCGIスクリプト)が必要なSQLサーバに比べると、より容易にバックアップできます。
また、SQLite Database Speed ComparisonにあるようにMySQLやPostgreSQLよりかなり高速に動作するようです。この比較には実はtrickがあるのですが、それに関しては後で触れます。
前説はこのくらいにして以降では使い方などについて述べます。
インストール
mt-check.cgiでDBD::SQLiteモジュールが見つからなければインストールする必要があります。CPAN(search.cpan.org: Matt Sergeant / DBD-SQLiteからダウンロードできます。また、SQLite home pageからは何もダウンロードする必要はありません。DBD::SQLiteモジュールにすでにバンドルされているためです。
注意する点としては、現状最新の1.0.4(SQLite 3.0.4beta相当)はMovable Typeからうまく使えないので、0.3.1(SQLite 2.8.12相当)をインストールしなくてはならないということです。インストール方法は、Techknow Movable Type: CPANモジュールのインストール方法の「CPAN シェルを使わずにインストールする」を参考にしてください。CPAN Shellで「install DBD::SQLite」とかやってしまうと、最新版がインストールされてハマること請け合いです。
レンタルサーバへのインストール
通常、レンタルサーバにはDBD-SQLiteはインストールされていないようです。Lolipopで使いたい場合には以下のいずれかのzipファイルをダウンロードしてください。
Lolipop-DBD-SQLite-0.31.zip (182KB)
Lolipop-DBD-SQLite-1.08.zip (195KB)
このzipファイルを展開すると得られるSQLite.soを$MT_DIR/extlibに、SQLite.pmを$MT_DIR/extlib/DBDに、それぞれコピーすると使えるはずです。ロリポップ以外でも環境によっては利用できると思います。
設定方法
mt.cfgで以下のように設定します。DBUser、DBHost、またmt-db-pass.cgiは設定する必要がありません。
ObjectDriver DBI::sqlite Database mtdb # DBUser <database-username> # DBHost localhost
Databaseで指定するのはDBイメージのファイル名です。上記のように単に「Database mtdb」と指定するとmt.cfgがあるディレクトリにmtdbというイメージファイルが作られます。「Database db/mtdb」とするとdbディレクトリの中にmtdbというイメージファイルが作られます。
あとはTechknow Movable Type: Movable Type のインストールなどを参照して適宜インストールするだけです。
性能
SQLite Database Speed Comparisonの計測結果にも関わらず、SQLiteの処理速度(特にINSERT、UPDATE)はそれほど高くはないと言われています。端的に言うと、SQLite(およびDBD-SQLite)の既定の動作(AutoCommitモード)では、書き込みを伴うSQLオペレーション一個ごとにグローバルロックを獲得し、物理ファイルイメージ上での処理が完了する(ありていに言ってfsyncが返るまで)まで離さないのです。したがって連続するINSERT/UPDATEは、非常に効率が悪くなります。上記URLにあるような一般的なSQLサーバに対する優位性を主張するのはやや強引と言えるでしょう。
もちろん、ユーザライブラリの実装としては、通常オペレーション発行後プログラムが異常終了する可能性を考えたら当然の選択です。その代わりに明示的にトランザクション区間を定義すれば、Commit時にのみ反映されるようになって効率は劇的に改善します。
Satoshi's Blog : SQLite の INSERT は遅いのか?
【特集】生まれ変わるPHP - Zend Engine 2、SQLiteの実力は? (8) MySQLとSQLiteの比較 - 大量のデータの書込みでは? (MYCOM PC WEB)
Movable Typeではと言うと、常にAutoCommitしています。そこで、仮にCGIの実行一回を一個のトランザクション区間とみなすように改造したもの(SQLite-trans)を用意して、ちょっとした比較実験を行ってみました。
実験環境は、SUSE Linux 9.1(ReiserFS) on VMware 4.5.2ですのでDisk I/Oが通常のサーバーより相当ショボイものと考えてください(下記の結果では使うDBによって性能差が非常に大きいですが、実際にはもっと差がない場合が多いということです)。
以下のグラフは、25個(445Kbytes)、200個(3564Kbytes)のエントリ(中身はGNU Public License)をBerkeleyDB版、MySQL版、SQLite版、SQLite-trans版でそれぞれimportするのにかかる時間をTime::Elapseモジュールを使って計測したものです。
こちらはBenchmarkモジュールでCPU Timeを計測したもの。
オリジナルのSQLite版は、BerkeleyDBと同等以上の性能でしかなく、率直に言ってショボイです。しかし、トランザクション機能を使えば、MySQL版以上の性能が出るようです。それにしても…、PerlのCPU Timeって謎。なんでこんなにSQLiteのSystem Timeが小さいのだろう。
どうやらファイルシステムの影響が大きいようなので、同じ実験をFedora Core 2(Ext3) on VMware 4.5.2でもやってみました。
思いがけずSQLite、SQLite-transが速いです。ReiserFSもExt3もJournaling Filesystemなのですが、fsyncしたときに物理ファイルにちゃんと反映するか、単にJournaling logに反映されるだけかと言う、システムコールの振る舞いの違いが関わっていそうです。
このエントリーのトラックバックURL: http://as-is.net/mt/mt-tb.cgi/174








いろいろと参考になります。Mac OS X 10.4(コードネーム Tiger)で SQLite が標準で入るらしいので Mac ユーザとしては SQLite が気になっているところでした。
トランザクション対応版が本家に採用されると嬉しいのですが :)
コメントありがとうございます。
トランザクション対応ですが、数行書き換えただけなので「こんなんで動いちゃうのかよっ!!」という感じです。こういう時は何か致命的な問題があるので…。SixApartのbug track systemにも婉曲的(?)に修正案を書いておいたのでひょっとしたら考慮してくれるかもしれません。