3

私は教育研究用のオンラインアプリケーションを開発しています。そこでは、非常に複雑なSQLクエリが頻繁に必要になります。

  • クエリには通常5〜20の結合が含まれ、多くの場合、同じテーブルに数回結合されます
  • SELECTフィールドは、派生フィールド/計算とCASEステートメントの間で、多くの場合30〜40行の高さになります。
  • ユーザーの権限やその他のセキュリティ設定に基づいて、PHPに追加のWHERE条件が追加されます
  • ユーザーインターフェイスには、WHERE / ORDER/HAVING句にカスタム句を追加するための検索および並べ替えコントロールがあります。

現在、このアプリは可動部分のPHP + MYSQL+Jqueryに基づいて構築されています。(これは古いDreamweaverコードから生まれました。)まもなく、アプリケーションを最初から再構築し、統合、クリーンアップ、および将来の拡張に備えることを目的としています。私はPHPに慣れていますが、Railsについて少し学び、気づいています。代わりに、より新しいフレームワークでバージョン2.0をビルドする方がよいかもしれません。しかし、何時間ものチュートリアルに取り組む前に、Railsクエリシステム(ActiveRecord?)がクエリのニーズを満たすかどうかを知る必要があります。

これが私が懸念している1つのクエリチャレンジの例です。クエリは、テーブルの3つ以上の「インスタンス」から選択し、各インスタンスから比較可能な情報を取得する必要があります。

SELECT p1.name AS my_name, pm.name AS mother_name, pf.name AS father_name
FROM people p1
    JOIN mother pm ON p1.mother_id = pm.id
    JOIN father pf ON p1.father_id = pf.id
    # etc. etc. etc.
WHERE p1.age BETWEEN 10 AND 16
# (selects this info for 10-200 people)

または、同様の例で、私たちの課題をよりよく表しています。「生データ」テーブルは「コーディング選択」テーブルに複数回結合され、各インスタンスは、格納されているキーに関連付けられたテキストを検索する必要があります。

SELECT d.*, c1.coder_name AS name_c1, c2.coder_name AS name_c2, c3.coder_name AS name_c3, 
    (c1.result + c2.result + c3.result) AS result_combined,
    m_c1.selection AS selected_c1, m_c2.selection AS selected_c2. m_c3.selection AS selected_c3
FROM t_data d
    LEFT JOIN t_codes c1 ON d.id = c1.data_id AND c1.category = 1
        LEFT JOIN t_menu_choice m_c1 ON c1.menu_choice = m_c1.id
    LEFT JOIN t_codes c2 ON d.id = c2.data_id AND c2.category = 2
        LEFT JOIN t_menu_choice m_c2 ON c2.menu_choice = m_c2.id
    LEFT JOIN t_codes c3 ON d.id = c3.data_id AND c3.category = 3
        LEFT JOIN t_menu_choice m_c3 ON c3.menu_choice = m_c3.id 
WHERE d.date_completed BETWEEN ? AND ?
    AND c1.coder_id = ?

これらの種類の結合は、純粋なSQLで簡単に記述できます。検索フィルターやその他のさまざまな要素が必要な場合は、いくつかのPHPループを使用して、文字列をまとめて完全なクエリにすることができます。しかし、この種の構造に対処するRails/ActiveRecordの例は見たことがありません。find_by_sql( "")を使用してすべてのクエリを純粋なSQLとして実行する必要がある場合は、Railsを使用しても、私が知っているPHPを使用するよりも大幅に改善されることはありません。

私の質問は次のとおりです。ActiveRecordは、上記のクエリのように、テーブルに「ニックネーム」が必要な場合をサポートしていますか?プライマリテーブルにもエイリアスを設定できますか?(私の例では、「p1」または「d」)SELECTステートメントで選択されるフィールドをどの程度制御できますか?選択したフィールドのエイリアスを作成できますか?SELECT句で計算を行って派生フィールドを選択できますか?CASEステートメントはどうですか?

結合されたテーブルのエイリアスを指定するWHERE条件を設定するのはどうですか?WHERE句に(上の例を使用して) "WHERE pm.age BETWEEN p1.age AND 65"のようなものを含めることはできますか?

この種の複雑さは、たまに発生する奇妙なクエリではなく、アプリケーションの一貫した中心的な機能です(現在構造化されているため)。私の懸念は、これらのクエリを書くことがRails&ActiveRecord内で「可能」であるかどうかだけではありません。この種のニーズが「Railsway」によってサポートされているかどうかです。なぜなら、これらをたくさん書く必要があるからです。だから私はRailsに切り替えることでそれが価値があるよりも多くの問題を引き起こすかどうかを判断しようとしています。

前もって感謝します!--Railsでの大きな恐ろしいクエリについて同様の経験がある場合は、あなたの話とそれがどのように機能したかを聞いてみたいと思います。

4

1 に答える 1

0

簡単な答えは「はい」です。Railsは、さまざまなタイプのリレーション、スコープなどを通じてこれらの要件の大部分を処理します。最も重要なことは、必要なタイプのクエリと機能をサポートするようにアプリケーションを適切にモデル化することです。人に説明するのが難しい場合、一般的にレールで行うのは非常に困難です。「現実世界」タイプの関係とタスクのほとんどを処理するように最適化されているため、「例外」をこの規則に適合させるのはやや困難になり、後で保守、管理、開発、分離などが困難になります。結論として、レールは次のことができます。あなたのためにSQLクエリを処理し、SQLとその間のすべてSomeObject.all_active_objects_with_some_qualityを完全に制御できるようにします。SomeObject.find_by_sql("select * from ...")execute("update blah set something=''...)

レールの利点の1つは、プロトタイプをすばやく作成できることです。モデルコンセプトを作成してから、最も複雑なビジネス要件をテストします。これにより、開発中に直面する可能性のあるボトルネックや潜在的な問題に対して、何が可能で簡単に実行できるかを簡単に把握できます。

于 2012-10-12T20:07:56.497 に答える