Next Previous Contents

3. 付録:データベース簡易リファレンス

ここでは poko2 のメインターゲットとなる MySQLPostgreSQL データベースの操作について極々簡単にまとめておきます。
テストツールやサンプルを動かすとき、データベースを扱います。その時用の簡易 リファレンスとして使って下さい。

データベースのホストOSは Linux を想定しています。Windows の場合、 MySQLはコマンドプロンプトから Linux と同様の操作になりますし、 PostgreSQLCygwinを利用しますのでやはり Linux と同様の操作 になるので省略します。
対象となるDBのバージョンは・・・

とします。メジャーバージョン(MySQL:3.x or PostgreSQL:7.2.x)が 同じであればその他のバージョンでも同様だと思われます。

なお、以下の説明で誤りがあれば遠慮なく著者に御指摘下さい。著者は MySQLPostgreSQL の卓越した使い手、というわけではありません。
MySQL, PostgreSQL ともに本家の方から日本語ドキュメントが公開されて います。詳細はそちらを参照して下さい。

3.1 データベースユーザーの登録

レンタルサーバーなどの場合は、データベースサービスを申し込んだ時にデータ ベース用のユーザー名とパスワードが与えられていると思います。その場合は この章は読み飛ばしてしまって構いません。
自前でサーバーを用意して実験してる人や、サーバーの管理者を兼任している場合 は、データベースを利用するには(おそらく)そのユーザーを登録する必要がありま す。
(もしも「自分一人の実験機だから、rootやpostgresユーザーでも全然平気」と いう場合は読み飛ばしても大丈夫です。)

以下、MySQLPostgreSQL の二つのデータベースにおけるユーザー 登録に必要な作業を簡単にまとめます。

MySQLの場合

MySQL でのユーザーとは、一般に "ユーザー名" と " 接続元ホスト名" を "@" 記号で連結した文字列です。
(ホスト名の特殊な記述として、全ホスト名を表す " % " も使用できます。)
以下に幾つかの例を示します。

'%' があれば、localhost バージョンは不要ではないか、という質問 も出て来ると思います。それに関しては、ユーザー認証テーブルにおいてホスト 名が具体的なユーザーがより上位レコードとしてソートされるので優先されます。 それによるユーザー認証時間の短縮を狙っている・・・のでしょう、多分。

んで、実際の認証ではどうなっているのか・・・を説明します。簡単に。
恐ろしく直観的なイメージで説明してしまうと、MySQL では DB に対する ユーザー認証を次のようなマトリクステーブル(升目表)で処理します。

ユーザー名 / DB名 | mysql | test | user1 | user2 | ...
------------------+-------+------+-------+-------+-----
root@localhost    | O     | O    | O     | O     | ...
root@'%'          | O     | O    | O     | O     | ...
user1@localhost   | X     | X    | O     | X     | ...
user2@localhost   | X     | X    | X     | O     | ...
これを実装しているのが、mysql データベースの user テーブル と db テーブルです。(だから上記升目表では、管理者ユーザーを表す root ユーザーのみ mysql への接続が許可されているわけです。)
というわけで、これからの解説が分からなくなりそうだったら上記テーブルの中身を 眺めて下さい。

話を本筋に戻し、データベースの作成とユーザーの登録について概説します。
最初にデータベースを作成します。これは管理者権限のユーザー(デフォルトは rootユーザー)で作成します。

$ mysql --user=root --password mysql
mysql> CREATE DATABASE user1db
user1db が作成したデータベース名になります。大文字小文字は区別されますが、 Windowsからの接続やライブラリの関連で、なるべくシステム全体でどちらかに統一 すべきです。
実際にこのデータベースを使うには、mysql コマンドラインツールで以下の ように指定するか、接続した後、USE というSQLコマンドを使います。
$ mysql --user=root --password user1db
or
mysql> USE user1db
データベースの作成の詳細は、以下のリンクを参照して下さい。
3.3.1 データベースの作成および選択

続いてユーザーを登録します。
MySQL におけるユーザー登録とは、ユーザーにデータベースを操作する「権限」 を与えるというイメージです。「権限」を与えたり(GRANT コマンド)、剥奪 (REVOKE コマンド)したりすることによりユーザーの登録・削除・アクセス権限 の変更を実装しています。
GRANT, REVOKE コマンドの正確な書式やオプションは後述のリンクを参照 して下さい。ここでは、PHP を使って MySQL にアクセスする一般ユーザー を登録するための一般的なコマンドを示すにとどめます。

$ mysql --user=root --password mysql
mysql> GRANT ALL PRIVILEGES ON db_name.* TO user_name IDENTIFIED BY 'password'
これで、db_name データベースに対して一般的な操作権限を有する user_name ユーザーを登録できました。(もし既に同ユーザーが登録済であれば、上記権限と パスワードで登録情報が上書きされます)
user_name の書式は、先に述べたユーザー名と接続元を @ でつなげた文字列 になります。

パスワードを後から変更したいときは次のコマンドを実行します。

$ mysql --user=root --password mysql
mysql> SET PASSWORD FOR user_name = PASSWORD('password');

データベースの作成とユーザー登録は基本的に以上で完了です。詳細は以下のリンクを 参照して下さい。

PostgreSQLの場合

一般に、普通の制限ユーザーは

  1. データベースは自分で勝手に作れない
  2. 別のユーザーを勝手に登録できない
という制限が与えられます。よーするに、予め作ってあるデータベースのみ使う ように制限してあるわけです。勝手にぽこぽこDBやらユーザーを作られては困る わけです。
というわけで、PostgreSQL でユーザーを作るための簡易コマンド createuser のオプションは以下のようになります。
$ createuser -D -A ユーザー名
(もちろんこのコマンドはpostgresユーザーでしか実行できません)

ところが・・・これやってしまうと、そのユーザー専用のDBを作れなくなります。 いくらpostgresユーザーにsuしようが、

$ createdb -U ユーザー名 データベース名
してもユーザー名にはDBの作成権限が無いため、データベースを作成できない わけです。これじゃ卵が先か鶏が先かという話になり兼ねません。

PostgreSQL において、ユーザーがcreatedbできるか否かは pg_shadow テーブルの usecreatedb フィールドに依ります。
このフィールドはboolean型で、't'ならcreatedb可能 です。'f'ならばcreatedbはできません。

というわけで、つまりです。最初は createdb 可能なユーザーとして 登録し、データベースを作った後、pg_shadowusecreatedb フィールド を'f'に手動で変更、createdb 不可能にする という手法が 有効です。

$ su - postgres
(postgres)$ createuser -d  -A newuser
(postgres)$ createdb -U newuser -E EUC-JP newdb
(postgres)$ psql -l template1 ( or template0)

template1=# update pg_shadow set usecreatedb = 'f' where usename = 'newuser';
UPDATE 1
template1=# \q

(postgres)$ exit
$

もう一つ方法が有ります。PostgreSQLでは各DBへのアクセスをそのDBのオーナー という概念を用いて管理しています。テーブルを作ったり消したりは、そのDBの オーナーでないと実行できないというわけです。
んで、各DBのオーナーは前述の pg_shadow テーブルの usesysid で指定できます。各DBは pg_database というシステムカタログテーブル で管理されており、その中の datdba フィールドにオーナーユーザーの usesysid が設定されます。
もう一つの方法とは、最初から$ createuser -D -A でDB作成不可能として ユーザー登録してしまい、その後適当なDBをpostgresユーザーで作成、その datdba フィールドを作成したユーザーの usesysid にしてしまう。
・・・というわけです。

$ su - postgres
(postgres)$ createuser -D -A newuser
(postgres)$ createdb -E EUC-JP newdb
(postgres)$ psql -l template1

template1=# update pg_database set datdba = (
template1(# select usesysid from pg_shadow where usename = 'newuser'
template1(# )
template1-# where datname = 'newdb';
UPDATE 1
template1=# \q

(postgres)$ exit
$

pg_shadowpg_database 等の「システムカタログ」については、 PostgreSQLのサポートと保守を行っている株式会社SRAの日本法人が 提供している以下の日本語HTMLマニュアルを参照して下さい。
Chapter 3. システムカタログ
上記マニュアル群に、通常必要とされる操作の全てが解説されています。

ユーザーの権限を変更するにはもっと簡単な SQL コマンドも用意されています。

ALTER USER username
    [ WITH PASSWORD 'password' ]
    [ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ]
    [ VALID UNTIL 'abstime' ]
これはPostgreSQL独自の実装です。詳細はSRAの日本語HTMLマニュアルを探索 して下さい。

3.2 コマンドラインツールの簡易リファレンス

MySQLの場合(mysql)

mysql コマンドの主な使い方を紹介します。まずは $ mysql --help から の抜粋を示します。

Usage: mysql [OPTIONS] [database]
  -h, --host=...        Connect to host.
  -p[password], --password[=...]
        Password to use when connecting to server
        If password is not given it's asked from the tty.
  -P, --port=...        Port number to use for connection.
  -S  --socket=...      Socket file to use for connection.
  -u, --user=#          User for login if not current user.
ローカルマシンで実行しているMySQLサーバーに、root ユーザーで接続 するには:
$ mysql --user=root --password
(この後、パスワード入力プロンプトが表示されます。)
外部マシン、192.168.2.20 にて実行しているMySQL(ポート5432で実行中)に user1 ユーザーで接続する(パスワード無し)には:
$ mysql -h 192.168.2.20 -P 5432 --user=user1

mysql で接続した後は、様々なコマンドでデータベースを探索できます。

show databases;

データベースの一覧を出力します。

use dbname;

dbname データベースに接続します。

show tables;

現在接続中のデータベースに登録されているテーブルの 一覧を表示します。

describe tablename;

tablename というテーブル名の フィールド構造を示します。

show columns from tablename;

同上。

select database();

現在接続中のデータベース名を取得します。

その他、mysql コマンドラインツールの使い方については 等から調査を開始してみて下さい。

PostgreSQLの場合(psql)

psql コマンドの主な使い方を紹介します。

$ psql -l
利用可能なデータベースの一覧を出力して終了します。
$ psql -U user1 db1
user1 というユーザー名で db1 というデータベースに接続します。 パスワード認証が無いことを前提としています。
$ psql -U user1 -W db1
パスワード認証を使います。パスワード入力用プロンプトが表示されます。
$ psql -h HOSTNAME -p PORT -U user1 -W db1
外部PostgreSQLサーバーである HOSTNAME(ホスト名かIPアドレス)のポート 番号 PORT に対して、user1 というユーザー名で db1 データベース に接続を試みます。パスワード認証を使います。

psql コマンドの詳細に関しては、manをひくか 「II. PostgreSQL クライアントアプリケーション」の「psql」 を参照されると良いでしょう。

3.3 ファイルからSQLを呼び出すには

テストツールやサンプルの実行に先立ち、SQLクエリが記述されたファイル をデータベースに読み込ませ、テーブルの作成やデータの登録を実行させておく事が 良く有ります。そのとき必要なのが、SQLコマンドをファイルから読み込み実行する 機能です。
大概はコマンドラインツールのオプション機能になっています。

MySQLの場合(mysql)

リダイレクション (<) を使います。

$ mysql --user=user1 --password testsuite < simple_dbmanager.sql
Enter password: (パスワード入力)
user1testsuite データベースに接続し、simple_dbmanager.sql に記述されているSQLコマンドを先頭から順番に実行します。

PostgreSQLの場合(psql)

psql コマンドの -f オプションに続けて、SQLコマンドを記述した ファイル名を指定します。

$ psql -U user1 -f simple_dbmanager.sql testsuite
上のコマンドでは、テストツールの中の simple_dbmanager.php が使用する テーブルやデータを作成するSQLコマンドを記述したファイル、 simple_dbmanager.sqltestsuite データベースに対して実行して います。また、ユーザー名は user1 で接続します。

3.4 トラブルシューティング

MySQL

UNIX系のMySQLでは、設定によってはTCP/IP 接続では無く、UNIX独自 のファイルベースの通信手段である「ソケット」を介して接続を待機している場合 があります。
「ソケット」はファイルシステム上の特殊なファイルです。MySQLでは設定 ファイル my.cnfsocket 項目で指示しています。

(/etc/my.cnf)
[client]
port            = 3306
socket          = /var/lib/mysql/mysql.sock

[mysqld]
datadir         = /var/lib/mysql
port            = 3306
socket          = /var/lib/mysql/mysql.sock
上記設定だと(おそらく)TCP/IP 3306 番で待機するとともに、 /var/lib/mysql/mysql.sock ファイルからも待機しています。 この場合、mysqlコマンドからは次の二つのオプションが使用できます。
$ mysql -P(--port=) 3306
$ mysql -S(--socket=) /var/lib/mysql/mysql.sock
設定や、おそらくコンパイル時のオプションによってか TCP/IP 経由の 接続が使えない場合があります。そのようなときはsocket 変数を確認し、 ソケットファイルを介して接続してみて下さい。

ソケットファイル経由でしか通信できないときでも、mysql コマンドなら 接続できます。
ところがです。 問題はPHPから接続する場合です。PHP用のMySQL インターフェイスである mysql_connect のホスト部分は、 "host:port" 形式。この状態で "localhost:3306" してもつながらないわけです。
この場合、port 部分をソケットファイル名にすることができます。

mysql_connect("localhost:/var/lib/mysql/mysql.sock" ...);
とすれば良いわけです。poko2 インターフェイスなら、$SqlConfig 連想 配列で、

$SqlConfig = array(
        "DriverClass" => "mysql",
        "Host" => "localhost",
        "Database" => "testsuite",
        "Port" => "/var/lib/mysql/mysql.sock",
        ...

とすれば大丈夫です・・・と言いたいところですが、まだ完全では有りません。

これでも接続できない場合があります。
この場合、ポート番号に指示したソケットファイルの位置は単純に無視されている 可能性が有ります。ソケットファイルの場所は PHP 側でも設定で持っている 設定を使っているはずです。

(php.ini)
mysql.default_socket /tmp/mysql.sock
といった感じで。こうなるともはや、.htaccessファイル(Apacheの設定に よっては違う名前の場合も有る)を設置し、ディレクトリ単位で設定を上書きする 他ありません。(AllowOverride Options が有効である必要があります)

(.htaccess)
<IfModule mod_php4.c>
php_value mysql.default_socket /var/lib/mysql/mysql.sock
</IfModule>

PostgreSQL

PostgreSQL で忘れやすいのが TCP/IP 接続の有効化です。以下の 日本語マニュアルを参照すると問題が解決するかも知れません。


Next Previous Contents