他の RDBMS で動くシステムを MySQL にも対応させようとしたが、あきらめた話
この記事では、MySQL をどのように設定したかと、MySQL の何がシステムの移植を妨げたかについて記す。
MySQL は難しい。
Windows 環境への導入
設定
設定は C:/xampp/mysql/my-small.ini を my.ini としてコピーし、my.ini を編集することで行う。
文字コードの設定変数がどこに影響するか難しかったので各セクションに次の設定を追記した。
# あらゆるクライアント (プログラミング言語で使うとか、対話型ツールとか) [client] default-character-set = utf8 # たぶんサーバの設定 [mysqld] default-character-set = utf8 character-set-server = utf8 collation-server = utf8_general_ci skip-character-set-client-handshake # おそらく今回は使わない [mysqldump] default-character-set = utf8 # 対話型ツールかな? [mysql] default-character-set = utf8
データベースの作成
対話型ツールを使う。my.ini でパスワードを設定していないのでそのまま入れる。
> mysql -u root
ユーザの作成、データベースの作成、権限の設定とテーブルの初期化までをここで行う。
CREATE USER dbuser@localhost; SET PASSWORD FOR dbuser@localhost=PASSWORD('dbpassword'); -- ユーザを作成 SELECT User, Host FROM mysql.user; -- ユーザが作られたことを確認 CREATE DATABASE dbname DEFAULT CHARACTER SET utf8; -- データベースを作成 GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER ON dbname.* TO dbuser@localhost; -- ユーザにデータベースを操作する権限を与える USE dbname; -- データベースを選択 SET NAMES utf8; SOURCE init.sql; -- ファイルから SQL コマンドを読み込む
問題発覚
ここでテーブルを作成しようとしたところ、次のエラーメッセージが表示された。
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
調べてみると、MySQL では 1 テーブルにつき 1 カラムにしか DEFAULT CURRENT_TIMESTAMP を設定できない仕様だそうだ。んなアホな。
It need not be the first TIMESTAMP column in a table that is automatically initialized or updated to the current timestamp. However, to specify automatic initialization or updating for a different TIMESTAMP column, you must suppress the automatic properties for the first one. Then, for the other TIMESTAMP column, the rules for the DEFAULT and ON UPDATE clauses are the same as for the first TIMESTAMP column, except that if you omit both clauses, no automatic initialization or updating occurs.
http://dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html
メモ
- 仙石浩明の日記: 文字化けしていなくても MySQL 内の文字コードが正しくない場合がある
- 接続するたびに “SET NAMES utf8;” を実行しないとデータがおかしくなるという話
たとえば PHP で mysqli クラスを使う場合は次のように行う。
<?php $con = new mysqli('localhost', 'dbuser', 'dbpassword', 'dbname', 3306); if ($con->connect_error) { exit "Failed to connect.\n"; } $con->query('SET NAMES utf8'); $result = $con->query($query); // ...