よくある質問。最近、グループ内でのフィードバックを通して、この問題をまだ理解していない人が多いと感じました。今日はこの問題について明確に説明しましたが、yii2 ActiveRecord がどのように複数テーブルの関連付けを行うのか、またこの関連付けを最適化する方法を見てみましょう。
シーンの要件:
ユーザー テーブル user とユーザー チャネル テーブル auth があり、2 つのデータ テーブルが user.id と auth.uid によって 1 対 1 に関連付けられているとします。ここで、認証テーブルのソース チャネル ソースをユーザー リストに表示する必要があり、チャネルが検索可能である必要があります。
まず、gii を通じて user および auth シリーズ関連のモデルと操作を生成します。ここでは詳細な説明はありません。gii の操作については、xxx
を参照してください。引き続き重要な手順を見ていきましょう:
1. user テーブルに対応する AR モデル クラス commonmodelsUser.php を見つけ、このクラス ファイルに認証テーブルを関連付けます
リーリー設定後、2 つのデータテーブルが自動的に関連付けられるわけではありません。ユーザー リスト ページにアクセスします (リスト ページは GII によって生成され、これまで操作していません)。データベース クエリのデバッグを通じて、実際のクエリが認証テーブルに関連付けられていないことを確認するのは難しくありません
2. グリッドビューに関連テーブルのソースチャネルフィールドソースを追加します
リーリー上で、関連付けがないと言いましたが、auth.source を直接使用するにはどうすればよいですか?
心配しないでください。デバッグを開いて実際のクエリを確認します。
select * from `auth` where uid = xxx; のような多くの操作があることがわかります。ページングのデフォルトが 20 個のデータである場合、同様のクエリが 20 個存在します。
まず何が起こったのか見てみましょう?
実はこれがphpの基礎知識です。オブジェクトの存在しないメンバー変数を読み書きする場合、__get() __set() マジック関数が自動的に呼び出されます。 Yii もこれを利用して実装しています。
この操作は、ほとんどの人がグリッドビューで関連テーブル データをカプセル化する方法とほぼ同じですが、! 20 個の SQL クエリでは、明らかにオーバーヘッドが大幅に増加します。これが左結合操作であれば素晴らしいでしょう。
3. SQL を最適化する
最適化する必要があるのは次のとおりです:
20 SQL が 1 SQL になります
関連テーブルに必要なフィールドのみを取得します
何人かの学生が叫んでいます。これが Yii に付属している操作です。それを最適化するにはどうすればよいですか?データ ソースの取得に戻り、ユーザー リストのデータが userSearch モデルの検索メソッドを通じて提供されていることがわかります。
つまり、データ クエリは実際には関連テーブル クエリを実行しません。この場合、UserSearch に関連クエリを追加します
リーリーユーザー リスト ページを再度更新してみましょう。デバッグ分析を通じて、2 つの SQL ステートメントが注目を集めていることがわかります
リーリーつまり、SQL の最適化という目標はデバッグ分析を通じて達成され、DB のクエリ時間が大幅に短縮されたことがわかりました。
4. 関連テーブルフィールドにクエリを追加します
gridview の検索モデルも、searchModel を通じて実装され、ルールによってどのフィールドが検索可能か、どのフィールドが検索不可能かを制御します。
次に、関連付けテーブルのソースを検索可能にする必要があるため、searchModel で属性ソースを定義し、それをルールに追加します
リーリー次に、gridview で auth.source を変更しましょう
リーリーこの時点で、インターフェースは問題ありません。プログラムによる検索を実装するためのステップがまだ 1 つ残っています。データ ソースを取得する場所に新しいソース条件を追加するだけです。 れーれー