- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- FAQ へ行く。
- 1 (2005-01-25 14:01:14 (火))
- 2 (2005-01-27 14:43:07 (木))
- 3 (2005-01-28 14:17:26 (金))
- 4 (2005-01-30 23:32:39 (日))
- 5 (2005-01-31 08:51:07 (月))
- 6 (2005-02-04 16:42:46 (金))
- 7 (2005-02-04 23:53:29 (金))
- 8 (2005-02-05 14:50:54 (土))
- 9 (2005-02-06 01:29:07 (日))
- 10 (2005-02-06 21:56:36 (日))
- 11 (2005-02-16 12:31:28 (水))
- 12 (2005-02-17 22:23:50 (木))
- 13 (2005-02-18 14:30:05 (金))
- 14 (2005-02-20 20:46:59 (日))
- 15 (2005-02-22 01:06:57 (火))
- 16 (2005-02-22 12:01:46 (火))
- 17 (2005-02-23 02:15:35 (水))
- 18 (2005-02-23 14:14:32 (水))
- 19 (2005-02-24 00:06:45 (木))
- 20 (2005-02-24 20:52:31 (木))
- 21 (2005-02-25 17:36:38 (金))
- 22 (2005-02-26 12:19:20 (土))
- 23 (2005-02-27 00:06:55 (日))
- 24 (2005-02-28 18:23:28 (月))
- 25 (2005-02-28 23:41:16 (月))
- 26 (2005-03-01 21:10:13 (火))
- 27 (2005-03-02 20:28:50 (水))
- 28 (2005-03-06 12:20:24 (日))
- 29 (2005-03-17 03:36:14 (木))
- 30 (2005-04-06 18:59:56 (水))
- 31 (2005-04-11 07:48:47 (月))
- 32 (2005-04-20 10:26:18 (水))
- 33 (2005-04-21 10:04:57 (木))
- 34 (2005-04-22 03:10:55 (金))
- 35 (2005-05-06 20:48:49 (金))
- 36 (2005-05-07 11:46:41 (土))
- 37 (2005-05-08 10:04:06 (日))
- 38 (2005-09-28 00:36:06 (水))
- 39 (2005-11-25 09:34:53 (金))
- 40 (2006-06-03 10:37:40 (土))
MySQLインストール †
mysqld が最低必要とする物 †
- basedir/share/ ディレクトリ以下(shareファイル。errmsg.sys や charsets/)
- datadir/mysql/ (mysql 権限データベース、テーブル)
権限テーブルや charsets/ がなければ mysqld は起動しない。
errmsg.sys はバージョンによって数が違うので、違うバージョンの errmsg.sys を使用していると mysqld が起動しない。
これらが起きた場合、.err ファイルにエラーが記録されないことが多い。
バイナリファイル †
- mysql-バージョン-ベンダ-OS-CPUアーキテクチャ.tar.gz
Unix, Unixライク用のバイナリ。
basedir は /usr/local/mysql/
datadir は /usr/local/mysql/var/
としてコンパイルされている
展開して、/usr/local/mysql/ にする。
- mysql-バージョン-win-noinstall.zip , mysql-noinstall-バージョン-win32.zip
ms-win用。
展開して、C:\mysql\ にする。
NT系列の場合、サービスに登録したければ、mysqld-nt --install を使う。
basedir は c:/mysql/
datadir は c:/mysql/data/
MySQL は Windows のレジストリには依存せず、コピーするだけで動く。
- mysql-バージョン-win.zip , mysql-バージョン-win32.zip , mysql-essential-バージョン-win32.msi
ms-win用。インストーラー付き。
インストーラーがおかしいことがあるので、こちらはあまり使わない。
mysql-バージョン-win-noinstall.zip (mysql-noinstall-バージョン-win32.zip) の方を使う。
Windows 用のバイナリ mysqld ファイル †
4.1バイナリ名 | named-pipe | BDB | |
mysqld.exe | 95系用 | - | - |
mysqld-max.exe | mysqld.exe の、フル機能バージョン | - | O |
mysqld-debug.exe | --debug オプションを有効にして作ったバイナリ | O | O |
mysqld-nt.exe | NT/XP 系用。named-pipe が使用できる | O | - |
mysqld-max-nt.exe | mysqld-nt の、フル機能バージョン | O | O |
MySQL サーバーの起動には、
- サービスで起動するか
- コマンドプロンプトで、直接 mysqld.exe を実行するか
- winmysqladmin.exe で起動するか
の方法がある。
起動しない場合は、
- c:\mysql\data\mysqld.err ファイルの中身を確認
- c:\mysql\share\ がちゃんとあるのか確認
- c:\mysql\data\ がちゃんとあるのか確認
Windows サービス †
- 登録
c:\mysql\bin\mysqld-max-nt.exe --install サービス名
mysqld のオプションを指定したい場合は:
c:\mysql\bin\mysqld-max-nt.exe --install サービス名 --defaults-file=c:/mymy.txt
のように、指定したいオプションをサービス名の後につける。
- 削除
c:\mysql\bin\mysqld-max-nt.exe --remove サービス名
登録と削除は同じバイナリで。
MySQL運用 †
OS選択 †
- 本格運用には、Unix, Unixライク OS を選ぶ。
- Linux は glibc 2.3 使用。
ストレージエンジン?? †
MySQL は、データの保存形式を複数持っています。 その保存形式により、機能や特徴、パフォーマンスが変わります。 これをストレージエンジンと呼んでいます。
このモデルの利点は:
- 用途にあったストレージエンジンを選択することで、特別なチューニングを施すことなく、その目的に合った能力を得ることができる。
- 古いバージョンのMySQLで作成したファイルは、MySQLをバージョンアップをしてもそのまま使い続けることができる。 MySQL のバージョンアップに際して、データの吸い上げ、入れ直しは発生しない。
- 新しい手法が登場したとき、簡単にその手法を取り入れ、よりよい環境を提供できる。
- あるストレージエンジンは他のストレージエンジンに影響を及ぼさない。 このため、バグの影響が少ない
実際の使い方は
CREATE TABLE ..... (.....) TYPE=InnoDB;
のようにするだけ。
ALTER TABLE .... TYPE=MyISAM;
のように、テーブルのストレージエンジンを ALTER TABLE 文で変えることも可能。(TYPEのかわりに ENGINE キーワードでも OK)
代表的なストレージエンジン:
- MyISAM : 検索に強い
- InnoDB : トランザクション
- NDB : クラスター
- HEAP(MEMORY) : メモリ内で動作するテーブル
標準のストレージエンジンは MyISAM。 すなわち、TYPE とか ENGINE を指定しなければ、テーブルの型は MyISAM になるということ。
複数のMySQLを同居させるには/MySQLを違うディレクトリで動かすには †
mysqld --basedir=/usr/local/mysql-4.0.22 --datadir=/usr/local/mysql-4.0.22/data --socket=/tmp/sock4.0.22 --port=4022 &
もしくは
/usr/local/mysql-4.0.22/my.cnf に
[mysqld] basedir=/usr/local/mysql-4.0.22 datadir=/usr/local/mysql-4.0.22/data socket=/tmp/sock4.0.22 port=4022
と書いて
mysqld --defaults-file=/usr/local/mysql-4.0.22/my.cnf &
I/O分散 †
MyISAMの場合
CREATE TABLE .... (...) DATA DIRECTORY = '/path/to/directory/MYD' INDEX DIRECTORY = '/path/to/directory/MYI'
InnoDB の場合1
[mysqld] innodb_data_home_dir = innodb_data_file_path=/path/to/file1:10M;/path/to/file2:50M
InnoDBの場合2
[mysqld] innodb_file_per_table
OSでの対処の場合
- データベースは単なるディレクトリなので、違うdiskをそのディレクトリにマウント
- データベースのディレクトリをどこかに移動して、シンボリックリンクを張る
ログとリカバリ †
log-bin (バイナリ更新ログ) が肝です。
# 3.22 までは、log-update (更新ログ) を使います。
log-bin 採取開始時のデータに対して、log-bin の内容(テキストのSQL文) を順に全て当てていけば、現在のデータになります。
もちろん、ログの途中まであてれば、その時までの状態になります。
roll forward リカバリですね。
どういう運用ができるかはあなたのアイデア次第。
- max_binlog_size : 1つのバイナリ更新ログファイルの最大サイズ。これに達すると、自動でローテート
- log-bin=名前 : バイナリ更新ログファイルの名前の指定。ディレクトリを含めることが出来る。 log-bin=/disk1/logfile とすると、/disk1/logfile.###### ファイルになる。
mysqlbinlog †
バージョン 4.1 の mysqlbinlog には、バイナリ更新ログの切り出しに便利なオプションがあります。
- --start-datetime=
- --stop-datetime=
- --start-position=
- --stop-position=
日本語環境の設定 †
標準のキャラクターセットが日本語になっていないバイナリを使用するときは、設定をしておきます。
[mysqld] default-character-set = ujis [mysqldump] default-character-set = ujis [mysql] default-character-set = ujis
なお、language = の指定は、日本語が扱える、扱えないには、全く関係ありません。設定しても無意味。
たんにエラーメッセージが日本語になるだけで、クエリやデータを日本語扱いにするという意味ではありません。
エラーメッセージが日本語になっても邪魔くさい(変な文だし、文字化けするかも)ので、通常は language は指定しません。
また、全てのアプリが my.cnf を読むわけではありません。勘違いしないように。
my.cnf を読むのは、原則、MySQL 付属のコマンドだけと思ってください。
それ以外は、アプリ側で読むようにコーディングする必要があります。
(この FAQ の「MySQL連携」を参照。)
my.cnf ファイルの読み込み順番 †
Unix系列の場合、
/etc/my.cnf → データディレクトリ/my.cnf → --defaults-extra-file=で指定されたファイル → ~/.my.cnf
なお、「データディレクトリ/my.cnf」 は、コンパイル時に指定されたデータディレクトリ固定です。
MS-Windows 系列の場合
%WINDIR%\my.ini → C:\my.cnf → --defaults-extra-file=で指定されたファイル
4.1以上の壁 †
MySQL 4.0 までは、3.X から 4.0 に upgrade しても、そのまんまなんの影響もなく古いデータを使えました。特にダンプしてリストアしなくても良かったし、ALTER TABLE も必要ありませんでした。
ところが、4.1 以上に upgrade するときは、我々日本語キャラクターセットを使う人間は、注意しなくてはならない点が複数存在します。
4.1 は、5.0pre だと思ってもいいぐらいの開きがあります。(4.0 と 4.1 を同じバージョン 4 だとは思わない方がいいという意味で。)
4.1 では何が変わったの? †
- CHAR(10) は 10 バイトから 10 文字に変わった。
- データベース、テーブル、フィールド、それぞれ個別にキャラクターセットを指定できるようになった。
- 文字コードの自動変換機能が追加された。
- パスワードの保存形式が変わった。(長くなった)
- mysqldump の標準キャラクターセットがどうコンパイルしても utf8 になる
- sub query の追加
- NDB クラスターの追加
- GIS追加
- utf8 キャラクターセットの追加
- データベース名、テーブル名は、OS 上では utf8 コードに直されて保存されるように変わった(ディレクトリ名、ファイル名が、utf8のコードで書かれるようになったということ)。4.0 まではバイナリ列がそのままデータベース名(=ディレクトリ名)、テーブル名(=ファイル名)になっていた。
- char() に、全てのバイト列が入らなくなった。例えば、ujis のフィールドには、EUC-JP に定義されるコード空間のバイトしか INSERT できない。全てを入れるパッチは http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib
- timestamp 型の表示フォーマットが変わった。4.0 までは 「20050116214504」 であったが、4.1 では 「2005-01-16 21:45:50」。アプリの作り方に注意。
- HEAP(MEMORY) テーブルのインデックスに、BTREE が加わった。4.0 までの HEAP テーブルは HASH のみ。(i int, INDEX USING BTREE (i)) TYPE=MEMORY;
CHAR の定義の違いによる弊害 †
これは 3.X, 4.0 から 4.1 に upgrade したときに遭遇する問題です。
3.X, 4.0 で char(10) と定義していたフィールドが、
4.1 に uprade した瞬間に、char(3) もしくは char(5) 扱いになってしまいます。
なぜか?
- ujis は、最大で 3バイトを使用して 1文字を表現する。sjis は最大で 2バイトを使用して sjis 1文字を表現する。
- 4.0 で CHAR(10) と定義した。これは 10 バイト。
- 4.1 に upgrade したら、10バイトを、X文字にしなければならない。
- そこで、ujis の場合は、10バイト -> 3(ujis)文字となる。
文字コードの自動変換機能による弊害 †
4.0 までは、キャラクターセットはサーバーだけが設定するものであり、クライアントがサーバーのキャラクターセットに自動的に合せて動作していました。
ところが
4.1 になってから、サーバー、クライアントがそれぞれのキャラクターセットで動作するようになりました。
例えば、
- クライアントが sjis で動作
- サーバーが ujis で動作
している場合、サーバーは、クライアントに対しては常に sjis のデータを送るようになります。
サーバーは ujis のデータを sjis に変換して、クライアントに送るのです。
これは一見便利です。
が、落とし穴があります。
- 変換できないキャラクターセットの組み合わせの場合
- 変換しきれない文字があった場合
こういう場合は、文字が ? になったり、期待外れの文字になったりします。
例えば、
- クライアントが latin1 で動作
- サーバーが sjis で動作
の場合、どうやって sjis を latin1 の文字コードに変換できるというのでしょう?
出来るわけがないので、sjis 文字はあえなく全て ? になってしまいます。
(え、「?」にしなけりゃいいのにって?
私もそう思います。変換できなければ「?」にせず、そのままのバイトのままにしておけば クライアントが latin1 でも問題が少なかったかもしれません。が、仕様が「?」に変換なので、なんとも。)
例えば、
UTF を使用してアプリを作っている方は経験されているでしょうが、
UTF の変換マップというのは統一が取れていません。
同じことが MySQL にもおきています。
MySQL が変換するコードと、あなたが使用している環境が考えるコードと文字の形の組み合わせが一致するとは限りません。
では、クライアントが latin1 で、サーバーが ujis,sjis の状況というのは、起きうるものなのでしょうか?
困ったことに、現状では簡単にこの状態が引き起こってしまいます。
あなたが使用している PHP は、自分でコンパイルしましたか?
あなたが使用している MySQL は、ご自身の手でコンパイルしましたか?
ほとんどの方が、他の誰かがコンパイルしたものを使用していると思います。
では、あなたが使用している PHP, MySQL のライブラリ(libmysql.dll, libmysqlclient)の標準キャラクターセットは何かご存じですか?
そう、ここが問題なのです。
日本人以外のデベロッパーが作ったバイナリは、ujis,sjis を標準のキャラクターセットにしているわけがありません。
事実 MySQL AB 配布のバイナリは、latin1 が標準です。
それらのバイナリを使って PHP の MySQL モジュールを動かせば(作成すれば)、クライアント(PHP)は latin1 で動作し、サーバーは ujis,sjis で動くことになるのです。こうして日本語文字は破壊されます。
これらの問題を避けるには、方法は2つ。
- PHP(Ruby,Perl,C,...)のアプリの変更。サーバーに接続した後にすぐ、"SET NAMES キャラクターセット名" という SQL 文を実行する
- PHP(Ruby,Perl,C,...)の MySQL モジュールの標準キャラクターセットを、自分が使うキャラクターセットにする。これはアプリの変更はない。しかし、libmysql.dll, libmysqlclient のコンパイルし直しが発生する。
mysqldump の仕様変更の弊害 †
mysqldump は、3.X, 4.0 までは、コンパイルするときに指定されたキャラクターセットを標準としていました。
4.1 からは、mysqldump はコンパイル時のキャラクターセットを無視して、utf8 を標準とします。(ひどい。普通、mysqldump のキャラクターセットは、mysqlコマンドとかのキャラクターセットと同じだと思って使うよなぁ...)
これは、4.1 の文字コード自動変換機能と組合わさって、最低な状況を起こしてしまいます。
サーバーが ujis, sjis で動いていたとしても、utf8 に変換して dump します。
utf8 はご存じの通り、到底整理されているコードとは言い難く、そのため、dump した内容が壊れる可能性が高いです。
これを避けるためには、mysqldump を実行するとき、必ず default-character-set オプションを指定すべきです。
個人的には以下が好みです。
[mysqldump] default-character-set=binary skip-opt hex-blob
なお、コンパイル時のキャラクターセットを mysqldump が無視しなくなる、
mysqlコマンドと同じキャラクターセットと同じにするパッチは以下にあります。
http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib
パスワード保存形式の変更 †
4.1 からは、パスワードの長さが長くなりました。
しかし、3.X, 4.0 までのパスワードはそのまま使えます。 3.X, 4.0 までの mysql データベースの内容は、そのまま引き続き使用できます。
例
Password | |
4.0まで | 12de31820cbc0fce |
4.1 | *59170D1E4A5E56267B6ED9C51ED62619FB817E6B |
3.X, 4.0 から 4.1 に upgrade して、mysql_fix_privilege_tables を実行しても、4.0 までの時代に設定した短いパスワードは変更されません。上記例では '12de31820cbc0fce' のままです。
4.1 であたらしくパスワードを設定した場合、'*59170D1E4A5E56267B6ED9C51ED62619FB817E6B' の形式になります。
4.1 のクライアントは、長い方のパスワードでも短い方のパスワードでも認証可能です。
4.0 までのクライアント( libmysqlclient , libmysql.dll ) と 4.1 のサーバーは、長い方のパスワードを使用したら、必ず認証失敗になります。
(「Client does not support authentication protocol requested by server;」)
4.0 までのクライアントと 4.1 のサーバー間の認証が成功する条件は、
- 保存されているパスワードが短い方の形式である場合
- 4.1 サーバーを4.0までのパスワード形式のみで動作させている場合 に限ります。
4.1 サーバーを4.0までのパスワード形式で動作させるには
[mysqld] old-passwords
を指定します。
これは 4.1 サーバーが生成するパスワードの形式を、4.0 までの短い方にするオプションです。
データベース名、テーブル名、フィールド名は、utf8 コードに直されて保存されるように変わったことの弊害 †
MySQL は、データベースをディレクトリ、テーブルを(基本的に)ファイルで表現します。フィールド名は .frm ファイルに記録されています。
4.0 まではバイナリ列がそのままデータベース名(=ディレクトリ名)、テーブル名(=ファイル名)、フィールド名になっていました。
ところが 4.1 からは、ディレクトリ名、ファイル名、フィールド名が、utf8のコードで書かれるようになったのです。
このために、4.0 までの MySQL で作成した日本語データベース名、テーブル名、フィールド名は、サーバーを 4.1 に upgrade したとたん、使えなくなります。
4.0 までに使用していた日本語のデータベース名、日本語のテーブル名、日本語のフィールド名を 4.1 に引き継ぐためには、
- 4.0 までのデータを一度フルダンプして(ファイルのコピーじゃ駄目)、
- 4.1 にバージョンアップしたあとに、
- フルリストアする必要があります。
3.X,4.0 -> 4.1 以上の手順 †
- クライアントの upgrade
Ruby, PHP, Perl など、C クライアントを 4.1 (以上)の libmysqlclient にリンクし直してインストール。
なお、文字の自動変換機能による弊害が発生する可能性があるので、他のFAQを参考のこと。
- 念のため、mysqldump でバックアップ
- upgrade
[mysqld] default-character-set = ujis old-passwords [mysqldump] default-character-set = ujis skip-opt [mysql] default-character-set = ujis
old-passwords オプションは、4.1以上のサーバーの認証方法を、4.0 までの認証方法のままにするということ。mysqldump は、標準では全てのデータを utf8 に変換してしまうという極悪な仕様に変わったので、それを避けるために default-character-set を指定。
- 権限テーブル upgrade
mysql_fix_privilege_tables もしくは
mysql -f -uroot mysql < mysql_fix_privilege_tables.sql
- 全ての CHAR(), VARCHAR() を ALTER する。 4.1 以上では CHAR(10) は 10文字を意味するようになったため。 http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib 他のFAQも参照
4.1サーバーと4.0クライアント †
[mysqld-4.1] old-passwords
MySQL 4.1 サーバーを 4.0 までの認証で動かす。 こうすれば、3.X, 4.0の libmysqlclient(libmysql.dll) をリンクしているアプリケーションと 4.1 サーバーがきちんと接続できる。
version 4.1 以上の文字コード変換機能とうまくつきあうには? †
MySQL version 4.1 から、utf8 が組み込まれたり、文字コードの自動変換が組み込まれたりと、けっこう文字周りがかわりました。 4.0までの MySQL とは感覚が変わるので、一応、こうした方がトラブルは少ないね、という経験上のものを書いておきます。
- mysqldump には必ず --default-character-set= を指定すること。
- MySQL サーバーとクライアントは、必ず同じキャラクターセットにしておくこと。
- 4.1以上対応のアプリケーションには、必ず "SET NAMES キャラクターセット名" という SQL 文を、サーバーに接続した直後に実行すること。
- データベース名、テーブル名、フィールド名には、マルチバイト文字は使用しないこと。
- マルチバイトキャラクターセットと、latin1などのシングルバイトキャラクターセットを混在させないようにすること。
- キャラクターセットはデータベース単位、テーブル単位、フィールド単位で指定できるが、フィールド単位でのキャラクターセットの指定はなるべく避けた方がよいだろう
- 文字の自動変換機能を抑止する、--default-character-set=binary の使用が便利。
- 既にコンパイル済みのバイナリを使うときは、そのバイナリが作成されたときに埋め込まれている、標準のキャラクターセットを知っておいた方がよい。
- !!! MySQL AB のバイナリは latin1 が標準 !!!
- 自分でコンパイルする場合は、binary キャラクターセットを標準に指定してコンパイルすれば、アプリの変更や設定の変更無しに、MySQL 4.0,3.23 対象のアプリが動く。
- --init-connect='SET NAMES キャラクタセット名' は使わない。これはクライアントコマンドオプション --default-character-set= を無効にしてしまうから。
- 4.1 の mysqldump には --hex-blob というオプションが追加されている。これは BLOB のバイナリデータを壊さずに mysqldump 可能になる。
4.1 にupgradeしたら文字が?になります / 4.1 にしたらクエリの結果がおかしいことがある †
4.1 から文字の自動変換機能の追加、char() の仕様変更がありました。
なので、サーバーを 4.1 に upgrade すると、文字が ? になったり、文字が変になったり、クエリーの結果がおかしくなったりすることがあります。
4.1 に upgrade するならば、以下のようにします(アプリの変更をしないための方法)。
- まず、ソースから MySQL をビルドし直す。charset は binary にして。(後述、備考参照)
- ビルドしてできた libmysqlclient (windows の場合は libmysql.dll) を使用して、PHP, Perl, Ruby, などの MySQL モジュールをコンパイルし直す。
- サーバーを 4.1 にする前に、念のためバックアップを取っておく
- サーバーを 4.1 に upgrade する。
/etc/my.cnf には[mysqld-4.1] old-passwords [mysqld] default-character-set=使用するキャラクターセット名 [mysqldump] default-character-set=使用するキャラクターセット名 skip-opt [mysql] default-character-set=使用するキャラクターセット名
を書いて、4.1 の サーバー起動
- mysql_fix_privilege_tables を実行して、mysql データベースの権限テーブルを upgrade する。
Windows の場合は、mysql -f -uroot mysql < mysql_fix_privilege_tables.sql
とする
- すべてのテーブルを ALTER する。
char() の定義がおかしくなっているので、指定し直す。
Unix の場合は、MyNA の http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib にあるシェルスクリプトを使ってもよい。
- また、mysql コマンド、mysqldump コマンド等は、必ず、default-character-set= を指定して使用しましょう。
character-set はサーバーと同じにしましょう。
- アプリのソースを変更して対応する方法:
クライアントプログラムのソースに、'SET NAMES ' 文を追加する方法もあります。この場合は、1,2 の手順は必須ではなくなります。
MySQL サーバーに接続した直後に、'SET NAMES クライアントのキャラクターセット名' という SQL 文を実行します。
- 備考. ソースからのビルド:
Unix なら ./configure --with-charset=binary にする。 Windows なら、
include/my_config.h , include/config-win.h の
#define MYSQL_DEFAULT_CHARSET_NAME "latin1"
を
#define MYSQL_DEFAULT_CHARSET_NAME "binary"
に。
#define MYSQL_DEFAULT_COLLATION_NAME "latin1_swedish_ci"
を
#define MYSQL_DEFAULT_COLLATION_NAME "binary"
に。
いままでの説明の概念図 †
例えば、PHP のアプリケーションの場合、次のような階層構造になります。
(等幅フォントで見てね)
+---- PHPアプリ ---------+ | 例えば PHPMyAdmin など | | | | SET NAMES sjis; | <- SET NAMES を実行するのはこの層 +------------------------+ ↓↑ +------- PHP -------------+ | PHP エンジン | | ↓↑ | | PHP の MySQL モジュール | | mysql.so (UNIX) | | mysql.dll (Windows) | +-------------------------+ ↓↑ +----------------------------+ | libmysqlclient.so (UNIX) | +---- MySQL サーバー ------+ | libmysql.dll (Windows) | | | |標準キャラクターセット埋込 | ←→ [文字コード変換ルーチン] | <- こいつが曲者 | 例えば latin1 とする | | ↓↑ | +----------------------------+ | 内部の処理。結果を返す | SET NAMES が実行されない時 | | 埋込の標準charsetが使用される | サーバー側のcharsetは | これが曲者 | 例えば sjis とすると | | 「あ」は 0x82A0 | +--------------------------+ latin1 には 0x82A0 のコードがないので、「あ」は「?」に変換されてしまう。
char(10) が char(3) になるトリック 4.0 まで : 1 2 3 4 5 6 7 8 9 10 内部バイト: ■■■■■■■■■■ 4.1(ujis) : +----+-----+-----+ 1 2 3
結局、どうしろと? †
- MySQL-4.0, 3.X を現在運用しているひとは:
原則、今のままキープですね。
サーバーを上げるといくつか問題に遭遇します。
充分な検証の結果、解決の目処がたってから、サーバーをバージョンアップしましょう。
- これから新しく導入する人は:
はじめから 4.1 以上でも OK。
- ただし、4.0までのアプリの資産を流用したい場合は、old-passwords や default-character-set 、SET NAMES 文に注意しましょう。
- これから作るアプリには必ず 「SET NAMES キャラクターセット名」 を接続直後に実行しましょう。
- 4.1以上にバージョンアップするときに
- アプリの変更をしたくない人は:
- MySQL サーバー、クライアント、libmysqlclient (libmysql.dll) を使用する全ての クライアントをコンパイルし直す。
- アプリの変更をしてもかまわない人は:
- アプリのソースに、「SET NAMES クライアントのキャラクターセット名」 SQL 文を追加する。追加する位置は、MySQL サーバーに接続直後にする。
- old-passwords を指定しておく
- アプリの変更をしたくない人は:
MySQL連携 †
エスケープ †
クエリに与える文字列はエスケープしますが、基本的に MySQL 側が用意しているエスケープ関数を使うべきです。
キャラクターセットに従ってエスケープしてくれるからです。
SQLインジェクション対策のためにもエスケープは必要です。
C †
エスケープ †
- mysql_escape_string()
- mysql_real_escape_string()
を使う
my.cnf を読む †
mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, "/etc/my.cnf"); mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "groupname");
PHP †
エスケープ †
- mysql_escape_string()
- mysql_real_escape_string()
を使う
my.cnf を読む †
PHP version 4 の場合
読めない。[client] に書いても無駄。
http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib
のパッチを当てる。
PHP version 5の場合
mysqli モジュールに、my.cnf を読む関数が用意されている。
mysqli_options(connection, MYSQLI_READ_DEFAULT_FILE, "/etc/my.cnf"); mysqli_options(connection, MYSQLI_READ_DEFAULT_GROUP, "php");
NULL の扱い †
- DBのデータが NULL の場合、PHP は "" を受け取る。NULL と空文字の区別が出来ない。
Ruby †
エスケープ †
escape_string() メソッドを使う
my.cnf を読む †
my.options(Mysql::READ_DEFAULT_FILE, "/etc/my.cnf") my.options(Mysql::READ_DEFAULT_GROUP, "ruby")
NULL の扱い †
- DBのデータが NULL の場合、Ruby は nil を受け取る。空文字ではない
Perl †
エスケープ †
DBI の quote() メソッドを使う。
my.cnf を読む †
$dsn = "DBI:mysql:test;mysql_read_default_group=perl;mysql_read_default_file=/etc/my.cnf";
Java †
Connector/J †
MySQLインターナル †
追記型ですか? †
いいえ
vacuumありますか? †
いいえ。
かわりに
MyISAM の場合は、OPTIMIZE TABLE 文か、REPAIR TABLE 文をします。
InnoDB の場合は、ALTER TABLE () TYPE=InnoDB を実行します。
たまにやればいいでしょう
トランザクション分離レベル †
InnoDB | BDB | NDB | |
READ UNCOMMITTED | ○ | - | - |
READ COMMITTED | ○ | ◎ | ◎ |
REPEATABLE READ | ◎ | - | - |
SERIALIZABLE | ○ | - | - |
InnoDB の標準は REPEATABLE READ。
InnoDBの REPEATABLE READは、phantom read は起きない実装。
ロック †
InnoDB | 行レベルロック |
NDB | 行レベルロック |
BDB | ページレベルロック |
MyISAM | テーブルレベルのロック |
- InnoDB、NDB の場合
- 必ずテーブルに primary key を作ります。
- LOCK TABLES は使わないように。
- 明示的にロックしたい場合は、InnoDB では、SELECT .... FOR UPDATE、 SELECT ..... LOCK IN SHARE MODE を使う。
- NDB の SELECT .... LOCK IN SHARE MODE、SELECT .... FOR UPDATE は将来対応予定
マルチバージョニング †
InnoDB は マルチバージョニング を実装しています
MySQL開発 †
aclocal 手順 †
aclocal autoheader libtoolize --automake --force automake autoconf cd innobase aclocal autoheader libtoolize --automake --force automake autoconf
libtoolize --force を実行しないと libmysqlclient.so.14 じゃなくて libmysqlclient.14 になってしまう環境がある。
bitkeeper で取る †
初めて取得するとき
bk clone bk://mysql.bkbits.net/mysql-5.0 mysql-5.0
更新するとき
bk pull
コンパイラー †
- 使用禁止
gcc-2.96, egcs-1, gcc-2.8
MySQL ドキュメント †
種類 †
manual.texi | リファレンスマニュアル |
include.texi | リファレンスマニュアルと internals.texi が include。定数定義 |
reservedwords.texi | リファレンスマニュアルが include。SQL予約語一覧 |
is.texi | INFORMATION_SCHEMA マニュアル |
internals.texi | 内部構造マニュアル |
manual.cluster.texi | クラスター |
bitkeeper †
初めて取得するとき
bk clone bk://mysql.bkbits.net/mysqldoc mysqldoc
更新するとき
bk pull
texi の加工 †
- texi ファイル -[texi2html]-> HTML ファイル
- texi ファイル -[texi2dvi]-> dvi ファイル -[dvi2ps]-> PS ファイル -[ps2pdf]-> PDF ファイル
- texi ファイル -[texi2db]-> DocBook形式ファイル
- manual.texi -> HTML への変換の場合
- manual.html ファイルができる。
- manual.texi , include.texi , reservedwords.texi を同じディレクトリに置く。
- texi ファイルのあるディレクトリで、
texi2html -Verbose -nomenu manual.texi
とすると、manual.html が出来る。
これは 1ファイル。
もし、章ごとにファイルを分割したい場合はtexi2html -nomenu -split=chapter manual.texi
- texi2html はバージョンによってオプションが違うので注意。
- manual.texi -> dvi への変換の場合
- manual.dvi ファイルが出来る
- manual.texi と、texinfo.tex ファイル (TeX用の、スタイル定義ファイル) を同じディレクトリに置く。
- texinfo.tex ファイルは、ネット上を探す
- texi ファイルのあるディレクトリで、
texi2dvi manual.texi
とすると manual.dvi ができる
- texi2html は perl スクリプト。日本の書き方やマルチバイトの事を考えていないので、頑張って修正しましょう。
- texinfo.tex も日本語を考慮していないので、がんばって修正する。
その他 †
ライセンスはどうなっていますか?商用利用ではどうすべきですか? †
MySQL のライセンスは単純です。 GPL か コマーシャルライセンスか。
GPL では具合が悪い、GPL では条件に合わない、GPL に納得できない場合に、コマーシャルライセンスを購入すればOK。
それは商用利用するかどうかには関係がありません。
GPL については http://www.gnu.org/home.ja.html をご覧ください。
2000〜2001年ごろに、「GPLかコマーシャルライセンスか」への移行がありましたが、それ以前のライセンス(FPL)は 別物でした。
前のライセンス条項(FPL)は現在は適用されていません(無くなっています)。
古い情報で判断しないほうがお得です。
バグ報告、質問をする場合 †
以下を必ず情報に含める。
- mysqlbug の出力内容
- my.cnf の内容
- テーブルの構造
- 問題となるデータ, SQL 文
- 得られる結果、エラーメッセージ、.err ファイルの出力
- なにを、どうした時に、なにが起きるか、を書く