生のSQLを使用するのではなく、クエリビルダを使用する利点はありますか?
例えば
$q->select('*')
->from('posts')
->innerJoin('terms', 'post_id')
->where(...)
対:
SELECT * FROM posts WHERE ...
多くのフレームワークがこの種の抽象化レイヤーを使用していることがわかりますが、その利点を理解できません。
生のSQLを使用するのではなく、クエリビルダを使用する利点はありますか?
例えば
$q->select('*')
->from('posts')
->innerJoin('terms', 'post_id')
->where(...)
対:
SELECT * FROM posts WHERE ...
多くのフレームワークがこの種の抽象化レイヤーを使用していることがわかりますが、その利点を理解できません。
回答:
フレームワークを介したSQLの記述の抽象化。
SQLを手書きで書くこと自体はそれほど悪いことではありませんが、エスケープとサニタイズの問題が発生し始め、これは混乱に変わります。抽象化レイヤーは、これらすべてをバックグラウンドで処理し、コードをきれいにし、多くのmysql_real_escape_string()
呼び出しなどを行わないようにします。
さらに、これにより、SQLのさまざまな方言を考慮できるようになります。すべてのデータベースが同じように構築されているわけではなく、キーワードや特定の機能の構文にバリエーションがある場合があります。抽象化レイヤーを使用すると、バリアントの正しい構文を動的に生成できます。
抽象化レイヤーはパフォーマンスに影響を与える可能性がありますが、見返りとして受け取るコードの清潔さと堅牢性と比較すると、一般的に無視できます。
クエリビルダーは私の嫌いなものなので、使用を避けるために独自のフレームワーク(Apeel)を作成しました。
PDOを使用している場合(絶対に使用することをお勧めします)、入力の正当化は自動的に処理されます。
他の人が言ったように、データベース間の切り替えは簡単ですが、「最小公分母」機能をサポートする傾向があり、より高度な機能をサポートしないか、パフォーマンスが低下します。
1986年頃からデータベースを使用したシステムを開発してきましたが、その間、使用するデータベースを実際に変更している会社が、パフォーマンスの向上が必要なとき以外はめったにありませんでした。パフォーマンスを向上させるためにデータベースを変更する場合は、簡単にするためにクエリビルダーを使用するよりも、クエリを手動で最適化して新しいデータベースを最大限に活用する方がはるかに理にかなっています。
クエリビルダーの機能に慣れるのに費やした時間(より良いものに切り替えると再学習する)は、SQLを最適化する方法を学ぶのにはるかに生産的に費やされるでしょう。
とにかく、それを使用しない理由はありますが、一部の人々はそれらを愛しています。
理論的には?はい。グレン・ネルソンは、彼らがしばしばあなたを助ける方法を指摘しました。(適切なクエリビルダーの場合)。
実際には?常に理論に従っているわけではなく、実際に問題を引き起こす可能性があります。いくつかの一般的なDBMSに対してクエリビルダを使用しており、すべてが正常であるとします。次に、顧客は、選択したクエリビルダーでは処理できないいくつかの癖があるDBMSをヒットするように要求します。(古いバージョンのPervasiveで作業しなければならなかったときに、この問題が発生しました。)
だが!絶対にすべきことは、データアクセスレイヤーを分離し、必要に応じて新しいレイヤーに交換できることを確認することです。そうすれば、すべての機能を備えたクールなクエリビルダーを使用できますが、問題のDBにその奇妙な擬似SQLを使用する新しいクエリビルダーをプラグインする必要がある場合です。
クエリビルダーの実用的で日常的な利点は、コードの再利用とDRY原則に従うことです。
クエリビルダを使用すると、SQLの繰り返し部分をメソッドに入れることができます。そして、これらのメソッドを使用して複雑なSQLを作成します。例は、再利用可能なJOIN句などです。
function joinTaskWithClient($queryBuilder) {
$queryBuilder->join('task', 'contract', 'task.contract_id = contract.id')
->join('contract', 'client', 'contract.client_id = client.id');
}
したがって、使用法は次のようになります。
$queryBuilder->select('client.name')
->from('client')
->where('task.id=:task')->setParameter('task', 42);
joinTaskWithClient($queryBuilder);
お気づきかもしれませんが、クエリビルダを使用すると、SQL文字列を手動で収集する場合とは対照的に、SQLの一部を任意の順序で追加できます(たとえば、WHEREの後にJOIN部分)。また、ビルダーのパターンについて読んで、 その意図と利点を確認することもできます。
エスケープとサニタイズについては同意しますが、これはクエリビルダーなしでも実現できます。DBタイプ/方言の抽象化に関して-これは非常に理論的で疑わしい利点であり、実際にはほとんど使用されません。
私は私のカスタムSQLビルダー(Dialect)のreadmeファイルに基づいて回答を提供します
(プレーンテキストが続き、ライブラリ固有の参照が削除されました)
必要条件
特徴
上記の機能と要件は、SQL抽象化ビルダーを使用する理由をスケッチしていると思います
上記の機能のほとんどは、ほとんどのSQLビルダーでサポートされています(リストされているすべてがサポートされているとは思いませんが、私の知る限り)
使用例:
最後に、私が持っていたユースケースの例。基になるDBスキーマ(wordpress)が実行する必要があるデータクエリの種類に適さず、さらに一部のWPテーブル(投稿など)を使用する必要がある(したがって、完全に新しいテーブルを持つ)アプリケーションを構築していましたすべてのアプリケーションデータについてはオプションではありませんでした)。
その場合、カスタム/動的条件によってモデルを照会できるMVCのようなアプリケーションを作成できるため、クエリのハードコーディングはほとんど悪夢のようになりました。結合を使用して最大2〜3個のテーブルを照会し、条件をフィルタリングして、結合するテーブルを確認し、必要なエイリアスなどを処理する必要がある場合を想像してください。
明らかに、これはクエリ抽象化のユースケースであり、さらに、カスタムソフトビュー (モデルに適した1つのカスタムテーブルであるかのように結合されたテーブルの集合体)を定義する機能が必要でした(または少なくとも大きな恩恵を受けました) 。その後、はるかに簡単で、よりクリーンで、モジュール式で、柔軟性がありました。別の側面では、アプリケーション(コード)はクエリ抽象化レイヤーを(dbスキーマ)正規化ツールとしても使用しました。いくつかの人が言うように、それは将来性がありました。
明日、人々がいくつかの追加のオプションやデータが必要だと判断した場合、それを数行でモデルに追加して正常に動作するのは非常に簡単です。さらに、明日、人々がワードプレスを使用したくないと判断した場合(アプリケーションはプラグインとしてワードプレスに疎結合されているため)、数行のモデルを変更するだけです(定義のみ)新しいスキーマに適応するコード。
意味がわかりますか?
多くの場合、これらのクエリの引数の一部は、定数ではなく値です。現在、それらの多くは基本的にユーザーフォームの投稿から派生しています。したがって、SQLインジェクション攻撃には多くの可能性があります。そのため、本質的にクエリの形成には完全な検証が必要です。
さて、これは開発者を信用していないということではありませんが、クエリの形成は簡単かもしれませんが、あらゆる場所で検証チェックを繰り返すことは、偶発的に見逃したり、クエリを変更したがクエリを変更しないで検証チェックを更新しません。いくつかの初心者は、これを見逃すことのすべての危険さえ知っているかもしれません。したがって、クエリビルダーの抽象化は非常に重要です。
クエリビルダーは、内部でSQLを生成しながら、テーブルを選択してグラフィカルに結合できるGUIアプリであると思っていましたが、純粋なSQLクエリを作成する必要がない方法を提供するAPIをクエリビルダーとも呼ぶことを理解しました、そのため、SQLフレーバーの潜在的な違いを抽象化します。
このようなクエリビルダーを使用するのは良いことですが、それらに大きく依存している人はDBAに質問しない傾向があると思う傾向があります。
誤解しないでください。
テーブルではなくビューに対してクエリを作成する必要があると思います。正当な理由であるセキュリティまたはフィルタリングのためではありませんが、同じ理由で、具体的なクラスではなくインターフェイスに対してコーディングする必要があります:分離。ビューは「契約」のようなもので、OOPでインターフェースが「契約」と同じ方法です。基礎となるテーブルを変更できますが、プログラマに同じ「契約」を表示するようにビューを強制する限り、コードは壊れません。
繰り返しますが、誤解しないでください。クエリビルダーを使用してビューをクエリできますが、クエリを作成し、DBAに質問することで生成される調整プロセスとして多くのビューが存在するようになります。 。
クエリを記述しないと、特定のビューを作成する必要性を検出できないと考えるのは間違っていますか?
私に関係するもう1つのことは、初心者プログラマーがSQLを習得していないことです。SQLは、人が作成した最も美しいテクノロジーの1つです。