List:Japanese« Previous MessageNext Message »
From:Zen Kishimoto Date:October 5 2004 5:56am
Subject:Prepared Statement (訳)
View as plain text  
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
の訳

10月1日

この記事は(これが書かれた段階では)ガンマステージのMySQL 4.1の
新しい機能に関する記事のシリーズの4番目です。

Harrison Fisk

サーバーサイドのprepared statementはMySQL 4.1での新しい
機能です。この記事ではprepared statementが何か、なぜ
使うか、何時使うかどのように使うかを述べます。

サーバーサイドのprepared statementとはなんでしょうか。

Prepared statementはステートメントを一度定義して、それを
何回も違う引数で実行するものです。これはセキュリティを増し
なおかつ効率のよい方法で、アドホックなクエリのストリングに
置き換わるものです。典型的なprepared statementは以下のようです。

SELECT * FROM Country WHERE code = ?

「 ?
」はいわゆる場所とりです。上のクエリを実行するときはこの場所
に値がいります。ではどうして、prepared statementを使うのでしょう。

アプリケーションでprepared statementを使用することで、
セキュリティや性能の理由で幾つもの利点をもたらします。

Prepared statementはSQL のロジックとデータを分離することで
セキュリティを増加します。ロジックとデータを分離することで、SQL
インジェクション攻撃を回避することができます。通常のクエリを
扱っている場合、ユーザから受け取ったデータを処理するには
注意が必要です。これはシングル・クオート、ダブル・クオート、
バックスラッシュなどの文字をエスケープする関数を使用すること
に関係します。こういったことはprepared
statementを使用する際には不必要です。
データを分離することでMySQLは自動的にこういった文字を考慮して
おり特別な関数を使用してこういう文字をエスケープする必要が
ありません。

prepared statementでの性能向上はいくつかの異なった機能によります。
まず最初に、クエリを一度しかパースしなくてよいことです。
最初にステートメントの用意をした際、MySQLはステートメント
をパースしてシンタクスをチックして、クエリの実行の用意を
します。同じクエリを何回も実行するのであれば、そのオーバヘッド
は2度目からありません。あらかじめ、パースしてあることで例えば
なんどもINSERTステートメントを使うような場合、スピードが
増加します。

(注: MySQL 4.1ではまだないものの、将来の版では, prepared statement
の実行計画をキャッシュして現在必要なオーバーヘッドを減少します。)

2つ目の性能向上は新しいバイナリーのプロトコルによります。
今までのプロトコルはネットワークを介して転送する前に、
全てをストリングに変換していました。クライアントはデータを
ストリングに変換し(大抵の場合もとのデータより大きい)、ネットワーク
(か他の方法で)サーバに転送します。サーバはストリングをもとの
正しいデータタイプに変換します。バイナリー・プロトコルであれば
このオーバーヘッドがありません。全てのタイプはそのままの
形で(バイナリー形式)で転送されます。そのためCPUの使用も
削減され、ネットワークの使用も押さえることができます。

何時prepared statementを使用すべきでしょうか。

Prepared
statementは上の全ての場合に有益です。しかし、アプリケーション
の全てに適用すべきでもないし、できません。まづ最初にこれは
 DML (INSERT, REPLACE, UPDATE, とDELETE), CREATE TABLE, とSELECT
クエリに限られています。将来の版では他のクエリもサポートされ、
prepared statementのクエリのAPIはもっと一般的なものになります。

時として、prepared statementは普通のクエリよりも遅いとき
があります。理由はサーバーまで2往復するため、一度だけ実行される
だけのクエリであれば実行の速度が落ちます。そのような場合は
prepared statementで得られるセキュリティが性能を落としてまでも
必要か考慮する必要があります。

どうやってprepared statementを使用するのでしょうか。

MySQLで使用されるプログラム言語にはすでにサーバーサイドの
prepared statementへのサポートがあるものがあります。
現在サポートされていない言語も近々サポートされます。

prepared statementが実装された最初のAPIはCのAPIでした。このAPI
はアルファとベータサイクルの間に大きく変更されました。現在では
一般の使用に耐える程度に安定しています。 詳細は
レファレンスマニュアルの「"C API Prepared Statements」を参照
してください。

もう1つ のAPI はPHPです。 PHP 5 には新しい"mysqli"と呼ばれる
MySQLのインターフェースがあります。これに関してはPHPの
マニュアルのmysqliのセクションを参照してください。mysqli
拡張で提供されるAPIは殆どCのAPIに1対1で対応しています。
そのためPHPのAPIを学ぶ際にはCのAPIが参考になります。

PerlとJava のユーザはかなり長い間prepared statementを使って
きました。しかし、これらはクライアント側のprepared
statementでした。
クライアント側のprepared statementは同じようなセキュリティの恩恵
をもたらしますが、性能向上には至りません。でも心配いりません。
MySQL Connector/J は3.1のリリースでサーバーサイドprepared statement
をサポートします。Perlの DBD::mysql ドライバーは2.9ブランチの
次のリリースでサポートします。一番よいことはコードはすでに
使用するように書かれているので、ドライバーさえアップグレードすれば
新しい機能を利用できます。

.NETプラットフォーム用の新しいMySQL Connector/Net はprepared statements
のサポートを含みます。 (MySQL 4.1とそれ以降の版と一緒に使用する
サーバーサイドと前の版用のクライアントサイドのprepared statement)

サーバーサイドのprepared statementをサポートするConnector/ODBC
のリリース
は現在ありませんが、最新の版はドライバーなしでprepared statementを
エミュレートします。 サーバーサイドへのprepared
statementのサポート
は次の大きなリリースである3.53版のConnector/ODBCに含まれます。

最後にprepared statementにもSQLのインターフェースがあります。
これがどういうことかというと、使用しているプログラム言語に
APIのサポートがなくても、prepared
statementを使えるということです。3つ
の新しいSQL ステートメントがあります。PREPARE, EXECUTE, と
DEALLOCATE PREPAREです。これは新しいバイナリーのプロトコルを使用
しません。そのためテスト用かネイティブなAPIがないときに使って
ください。

mysql> PREPARE stmt_name FROM "SELECT name FROM Country WHERE code = ?";
Query OK, 0 rows affected (0.09 sec)
Statement prepared

mysql> SET @test_parm = "FIN";
Query OK, 0 rows affected (0.00 sec)

mysql> EXECUTE stmt_name USING @test_parm;
+---------+
| name    |
+---------+
| Finland |
+---------+
1 row in set (0.03 sec)

mysql> DEALLOCATE PREPARE stmt_name;
Query OK, 0 rows affected (0.00 sec)

最後に

これで何時prepared statementを使うのかの利点・欠点が分かったと
思います。prepared statementは正しく使用すれば速く、セキュアーな
コードへとつながります。現在のAPIと同時に使用すればお互いを
補完する関係となります。
---------------------
Zen Kishimoto                        zen@stripped
IP Devices, Inc.                       (408) 567-9391
2175 De La Cruz Blvd., Suite 10  (801) 720-8847 (FAX)
Santa Clara, CA 95050 


Thread
Prepared Statement (訳)Zen Kishimoto5 Oct