SQLクエリビルダーを使用する利点は何ですか?


17

生のSQLを使用するのではなく、クエリビルダを使用する利点はありますか?

例えば

$q->select('*')
  ->from('posts')
  ->innerJoin('terms', 'post_id')
  ->where(...)

対:

SELECT * FROM posts WHERE ...

多くのフレームワークがこの種の抽象化レイヤーを使用していることがわかりますが、その利点を理解できません。


テーブルに対してではなく、ビューに対してクエリを書くべきだと思います。クエリビルダーを使用する人は、ビューを作成したり、DBAにビューを作成するように依頼したりしない傾向があると思います。そうすることで、RDBMSのすべての力を活用しません。
Tulainsコルドバ

1
@ user61852:おそらくいくつかのセキュリティとフィルタリングを無料で提供する以外に、テーブルに対するクエリでは提供できないビューに対するクエリは何を提供できますか?
ロバートハーヴェイ

4
@RobertHarvey具象クラスではなくインターフェースへのプログラミングと同じこと。デカップリングと柔軟性。ビューである「契約」がこれまでと同じ列を「シミュレート」している限り、基礎となるテーブルの設計は偶然かもしれません。
Tulainsコルドバ

@ user61852まあまあ。
ロバートハーヴェイ

@RobertHarveyそれを答えに変えました。
Tulainsコルドバ

回答:


20

フレームワークを介したSQLの記述の抽象化。

SQLを手書きで書くこと自体はそれほど悪いことではありませんが、エスケープとサニタイズの問題が発生し始め、これは混乱に変わります。抽象化レイヤーは、これらすべてをバックグラウンドで処理し、コードをきれいにし、多くのmysql_real_escape_string()呼び出しなどを行わないようにします。

さらに、これにより、SQLのさまざまな方言を考慮できるようになります。すべてのデータベースが同じように構築されているわけではなく、キーワードや特定の機能の構文にバリエーションがある場合があります。抽象化レイヤーを使用すると、バリアントの正しい構文を動的に生成できます。

抽象化レイヤーはパフォーマンスに影響を与える可能性がありますが、見返りとして受け取るコードの清潔さと堅牢性と比較すると、一般的に無視できます。


1
SQLの方言はRDBMSによって異なるとは思わない。PHPには、uのサニタイズを行うPDOがあります
アンナK.

12
SQLダイアレクトは異なるため、ダイアレクトと呼ばれます。PDOに関しては、抽象化レイヤーはこの混乱を単に隠すだけです。

@GlennNelsonアンナは、異なるバックエンド(PSQL / MySQL / SQLite ...)を使用して、1つの方言を意味しました
Izkata

2
@AnnaK。方言は変わらないかもしれませんが、機能が異なる場合があります。たとえば、MySQL(MyISAMエンジン)は外部キーの制限をサポートしていませんが、PostGresはサポートしています。方言はそのようなこと自体を処理する必要があります(Django ORMのようにデータ構造の完全な知識を必要とします)、または、より可能性が高い:ユーザーはそれを使用する方法を賢くしなければなりません。方言が状況に応じて変化するように。
イズカタ

1
+1は、適切に構築されたツールでエスケープとサニタイズを行えるようにします。検証も行える場合は、さらに良いでしょう。
ダン・レイ

11

クエリビルダーは私の嫌いなものなので、使用を避けるために独自のフレームワーク(Apeel)を作成しました。

PDOを使用している場合(絶対に使用することをお勧めします)、入力の正当化は自動的に処理されます。

他の人が言ったように、データベース間の切り替えは簡単ですが、「最小公分母」機能をサポートする傾向があり、より高度な機能をサポートしないか、パフォーマンスが低下します。

1986年頃からデータベースを使用したシステムを開発してきましたが、その間、使用するデータベースを実際に変更している会社が、パフォーマンスの向上が必要なとき以外はめったにありませんでした。パフォーマンスを向上させるためにデータベースを変更する場合は、簡単にするためにクエリビルダーを使用するよりも、クエリを手動で最適化して新しいデータベースを最大限に活用する方がはるかに理にかなっています。

クエリビルダーの機能に慣れるのに費やした時間(より良いものに切り替えると再学習する)は、SQLを最適化する方法を学ぶのにはるかに生産的に費やされるでしょう。

とにかく、それを使用しない理由はありますが、一部の人々はそれらを愛しています。


4

理論的には?はい。グレン・ネルソンは、彼らがしばしばあなたを助ける方法を指摘しました。(適切なクエリビルダーの場合)。

実際には?常に理論に従っているわけではなく、実際に問題を引き起こす可能性があります。いくつかの一般的なDBMSに対してクエリビルダを使用しており、すべてが正常であるとします。次に、顧客は、選択したクエリビルダーでは処理できないいくつかの癖があるDBMSをヒットするように要求します。(古いバージョンのPervasiveで作業しなければならなかったときに、この問題が発生しました。)

だが!絶対にすべきことは、データアクセスレイヤーを分離し、必要に応じて新しいレイヤーに交換できることを確認することです。そうすれば、すべての機能を備えたクールなクエリビルダーを使用できますが、問題のDBにその奇妙な擬似SQLを使用する新しいクエリビルダーをプラグインする必要がある場合です。


2
DBの奇妙な状況のようなものを事前に解決すべきではないでしょうか?クライアントが使用しているDBを見つけ、それに応じて適切なフレームワーク/ライブラリを選択することは、1行のコードを記述するに処理する必要があることを意味します。

3

クエリビルダーの実用的で日常的な利点は、コードの再利用と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タイプ/方言の抽象化に関して-これは非常に理論的で疑わしい利点であり、実際にはほとんど使用されません。


私にとっては、これも大きなメリットです。もう1つの方法は、メソッドに抽象化することで、メソッドにより意味のある名前を付けたり、これからドメイン固有言語を作成したりすることができ、意図をより明確にすることができます。クエリビルダを渡すこともでき、さまざまなコンポーネントに特定のビットを追加さ​​せることができます。最後になりましたが、私はそれが意味のある名前のメソッドの背後にカプセル化パターンに私を認めた....私は...種類では役に立たない上記の多くをレンダリングする愚か上書き以前のものを列を追加するいくつかのクエリビルダを、発見した
マルタを

2

私は私のカスタムSQLビルダー(Dialect)のreadmeファイルに基づいて回答を提供します

(プレーンテキストが続き、ライブラリ固有の参照が削除されました)

必要条件

  1. 複数のDBベンダーをサポート(例:MySQL、PostgreSQL、SQLite、MS SQL / SQL Server、Oracle、DB2、..)
  2. 新しいDBに簡単に拡張(できれば、実装に依存しない構成設定を使用)
  3. モジュール性と実装に依存しない転送可能性
  4. 柔軟で直感的なAPI

特徴

  1. 文法ベースのテンプレート
  2. カスタムソフトビューのサポート
  3. dbの抽象化、モジュール性、および転送可能性
  4. 準備されたテンプレート
  5. データエスケープ

上記の機能と要件は、SQL抽象化ビルダーを使用する理由をスケッチしていると思います

上記の機能のほとんどは、ほとんどのSQLビルダーでサポートされています(リストされているすべてがサポートされているとは思いませんが、私の知る限り)

使用例:

  1. 複数のDBベンダーと連携できる(基礎となるコードを変更することなく)CMSプラットフォーム
  2. DBベンダーが変更しやすい、および/またはdBスキーマが動的であるカスタムアプリケーションコード(これは、多くのクエリをハードコーディングできないが、コードが変更に対して堅牢であるように十分に抽象化する必要があることを意味します)
  3. 実稼働で使用されているものとは別のDBを使用したプロトタイピング(少なくとも一部のコードには重複したコードベースが必要になります)
  4. アプリケーションコードは特定のDBプロバイダーや実装に密接に結合されいないため(同じDBベンダー内、たとえば異なるバージョンのDBベンダー内でも)、より堅牢で柔軟性があり、モジュール式です。
  5. クエリとデータエスケープの多くの通常のケースはフレームワーク自体によって処理され、通常これは最適かつ高速です。

最後に、私が持っていたユースケースの例。基になるDBスキーマ(wordpress)が実行する必要があるデータクエリの種類に適さず、さらに一部のWPテーブル(投稿など)を使用する必要がある(したがって、完全に新しいテーブルを持つ)アプリケーションを構築していましたすべてのアプリケーションデータについてはオプションではありませんでした)。

その場合、カスタム/動的条件によってモデルを照会できるMVCのようなアプリケーションを作成できるため、クエリのハードコーディングはほとんど悪夢のようになりました。結合を使用して最大2〜3個のテーブルを照会し、条件をフィルタリングして、結合するテーブルを確認し、必要なエイリアスなどを処理する必要がある場合を想像してください。

明らかに、これはクエリ抽象化のユースケースであり、さらに、カスタムソフトビュー (モデルに適した1つのカスタムテーブルであるかのように結合されたテーブルの集合体)を定義する機能が必要でした(または少なくとも大きな恩恵を受けました) 。その後、はるかに簡単で、よりクリーンで、モジュール式で、柔軟性がありました。別の側面では、アプリケーション(コード)はクエリ抽象化レイヤーを(dbスキーマ)正規化ツールとしても使用しました。いくつかの人が言うように、それは将来性がありました

明日、人々がいくつかの追加のオプションやデータが必要だと判断した場合、それを数行でモデルに追加して正常に動作するのは非常に簡単です。さらに、明日、人々がワードプレスを使用したくないと判断した場合(アプリケーションはプラグインとしてワードプレスに疎結合されているため)、数行のモデルを変更するだけです定義のみ)新しいスキーマに適応するコード。

意味がわかりますか?


1

多くの場合、これらのクエリの引数の一部は、定数ではなく値です。現在、それらの多くは基本的にユーザーフォームの投稿から派生しています。したがって、SQLインジェクション攻撃には多くの可能性があります。そのため、本質的にクエリの形成には完全な検証が必要です。

さて、これは開発者を信用していないということではありませんが、クエリの形成は簡単かもしれませんが、あらゆる場所で検証チェックを繰り返すことは、偶発的に見逃したり、クエリを変更したがクエリを変更しないで検証チェックを更新しません。いくつかの初心者は、これを見逃すことのすべての危険さえ知っているかもしれません。したがって、クエリビルダーの抽象化は非常に重要です。


0

クエリビルダーは、内部でSQLを生成しながら、テーブルを選択してグラフィカルに結合できるGUIアプリであると思っていましたが、純粋なSQLクエリを作成する必要がない方法を提供するAPIをクエリビルダーとも呼ぶことを理解しました、そのため、SQLフレーバーの潜在的な違いを抽象化します。

このようなクエリビルダーを使用するのは良いことですが、それらに大きく依存している人はDBAに質問しない傾向があると思う傾向があります。

誤解しないでください。

テーブルではなくビューに対してクエリを作成する必要があると思います。正当な理由であるセキュリティまたはフィルタリングのためではありませんが、同じ理由で、具体的なクラスではなくインターフェイスに対してコーディングする必要があります:分離。ビューは「契約」のようなもので、OOPでインターフェースが「契約」と同じ方法です。基礎となるテーブルを変更できますが、プログラマに同じ「契約」を表示するようにビューを強制する限り、コードは壊れません。

繰り返しますが、誤解しないでください。クエリビルダーを使用してビューをクエリできますが、クエリを作成し、DBAに質問することで生成される調整プロセスとして多くのビューが存在するようになります。 。

クエリを記述しないと、特定のビューを作成する必要性を検出できないと考えるのは間違っていますか?

私に関係するもう1つのことは、初心者プログラマーがSQLを習得していないことです。SQLは、人が作成した最も美しいテクノロジーの1つです。


「このクエリの実行は不十分です。一緒に作業して改善しましょう」と言うDBAはどうでしょうか。最初はうまく機能していたかもしれませんが、現在は問題に直面しています。必要なのがインデックスだけなら、なぜ開発者を困らせるのでしょうか?
ジェフ16

それはまったく異なる状況であり、まったく問題ありません。
Tulainsコルドバ

クエリがテーブルまたはビューから1つのレコードをプルするたびにDBAを関与させたいと感じているだけで、開発プロセスでボトルネックが発生します。
ジェフ16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.