6

PHP で mysql から mysqli 拡張機能を使用するようになりました。

同じことを行う 2 つの方法 (複数の更新クエリ) に遭遇しました。それぞれの長所と短所は何ですか? どちらかを使用する必要がありますか、それともまったく別のものを使用する必要がありますか?

ループ内の準備済みステートメント:

//prepare statement
foreach(whatever){
  //execute statement
}

また

マルチクエリ:

foreach(whatever){
  //build many queries into a single string
}
multi_query(long string)

プリペアド ステートメントの方がセキュリティが優れていることはわかっています。PHP で mysql を使用する場合、UPDATE ステートメントをループで使用しないようにするのが最善だと聞いたことがあります。

4

3 に答える 3

8

何らかの理由で、この PHP ループの必要性を完全に回避するために 1 つの mysql update ステートメントだけですべての対象レコードを更新できない場合は、この同じupdatemysqli ステートメント オブジェクトをループで再利用してもまったく問題ありません。

スタイルとリソースに関しては、パラメーター化されたステートメントを常に再作成するよりも、再利用するのが最善です。それを再利用することで、最初のbind_param呼び出しの後に行うことは、各反復でバインドされた PHP 変数の値を再割り当てすることだけですexecuting(例:mysqli_stmt->execute例 #1 オブジェクト指向スタイルを参照)。

句には、反復処理WHEREなどの別の PHP 変数割り当てパラメーターがあるだけであることを思い出してください。WHERE (recordID = ?)

パラメータ化された各ステートメントを最初に設定するには追加のリソースが必要になるため、複数のパラメータ化されたステートメントは、関連のない複数のステートメントまたはクエリを渡すために予約する必要があります。multi queriesまた、PHP の関数とメソッドはパラメータ化をまったくサポートしていないようです。

于 2011-02-22T03:00:47.407 に答える
7

他の 2 つの回答は、マルチクエリと準備済みステートメントの実際の違いには対応していません。完全に異なります。

  • プリペアド ステートメント - ステートメント テンプレートを 1 回作成し、テンプレートごとに異なる値を使用して複数回実行します (bind_param を使用)。ステートメントを設定するためのサーバー ラウンドトリップと、クエリごとに 1 回のラウンドトリップがあります。MySQL のバイナリ プロトコルを使用してデータを送信するため、実際には、通常のクエリよりも少ないデータを送信します。

  • マルチクエリ - 複数の通常の MySQL クエリを一度に実行するだけです。マルチクエリ全体で1回のサーバー ラウンドトリップが発生します。これにより、準備済みステートメントと比較してほぼ確実にパフォーマンスが向上します (クエリが異常に巨大で、変化する値が小さい場合を除きます)。

したがって、速度のためにマルチクエリをお勧めします。mysqli::real_escape_string を使用してデータを適切にエスケープすれば、安全性も劣りません。マルチクエリのもう 1 つの利点は、完全に異なるクエリをすべて同じリクエストで実行できることです。一方、準備済みステートメントはクエリの対称性に依存して利点を提供します。

于 2012-02-14T01:39:11.167 に答える
0

bob-the-destroyer は正しいです (準備済みステートメントを使用する方が良い)。いくつか追加したかっただけです。

  1. ループの後に実行することは、ループ内で毎回$mysqli->multi_query($sql)実行することと同じです。と just$mysqli->query($sql)の違いは、セミコロンで区切られた複数のクエリを受け入れないことです。multi_query を使用すると、実行された 2 回目以降のクエリのエラーをチェックするのが少し難しくなります。multi_queryqueryquery

  2. 誰かがループ内で UPDATE を発行するのを避ける理由がわかりません。ただし、ループをトランザクションでラップすることをお勧めします。これにより、クエリが失敗した場合にすべての更新をロールバックできます。

于 2011-02-22T11:00:27.777 に答える