最近、SQLはひどい言語だとよく耳にします。Sunの下のすべてのフレームワークには、データベース抽象化レイヤーがあらかじめパッケージ化されているようです。
しかし私の経験では、SQLは多くの場合、データの入力と出力を管理するためのはるかに簡単で、より用途が広く、よりプログラマーフレンドリーな方法です。私が使用したすべての抽象化レイヤーは、著しく制限されたアプローチであり、実際の利点はないようです。
SQLがこれほどひどいのはなぜですか。また、なぜデータベース抽象化レイヤーが重要なのですか。
これは部分的に主観的です。だからこれは私の意見です:
SQLにはpseudo-natural-language styleがあります。発明者たちは、英語と同じように言語を作成でき、データベースクエリは非常に単純であると信じていました。ひどい間違い。些細な場合を除いて、SQLの理解は非常に困難です。
SQLは宣言型です。あなたはデータベースにどうやってそれが何かをすべきかを伝えることができません、あなたが結果として欲しいものだけです。これは完璧で非常に強力です-パフォーマンスを気にする必要がない場合。つまり、SQLを書き、実行プランを読み、SQLを言い換えて実行プランに影響を与えようとすると、なぜ自分で実行プランを書けないなのかと疑問に思うでしょう。
宣言型言語のもう1つの問題は、一部の問題は命令型の方法で解決する方が簡単なことです。したがって、それを別の言語(標準SQLとおそらくデータアクセスレイヤーが必要です)で書くか、ベンダー固有の言語拡張を使用して、たとえばストアドプロシージャと書いてください。そうすることでおそらく、これまでに見た中で最悪の言語の1つを使用していることがわかるでしょう。
SQLは非常に古いです。 SQLは標準化されていますが、遅すぎるため、多くのベンダーがすでに言語拡張を開発しています。したがって、SQLは何十もの方言になりました。これが、アプリケーションに移植性がない理由であり、DB抽象化レイヤーがある理由の1つです。
しかし、それは本当です-実行可能な代替手段はありません。したがって、今後数年間はすべてSQLを使用します。
言われたことは別にして、抽象化レイヤーを価値あるものにするためにテクノロジーが悪いわけではありません。
非常に単純なスクリプトまたはアプリケーションを実行している場合は、コード内でSQL呼び出しを好きな場所に混在させることができます。ただし、複雑なシステムを使用している場合は、データベース呼び出しを個別のモジュールに分離することをお勧めします。これにより、SQLコードが分離されます。コードの可読性、保守性、テスト容易性が向上します。それはあなたがすべての高レベルのものなどを壊すことなくデータベースモデルの変更にあなたのシステムを素早く適応させることを可能にします。
SQLは素晴らしいです。その上の抽象化レイヤーはそれをさらに大きくします!
抽象化レイヤーの1つのポイントは、標準が少しあいまいであるため、また、ほとんどのベンダーが独自の(非標準)追加機能を追加しているため、SQL実装は互いに互換性がない傾向があるという事実です。つまり、MySQL DB用に作成されたSQLは、たとえ「適切に」実行されたとしても、たとえばOracle DBとまったく同様に機能しない可能性があります。
ただし、SQLは他のほとんどの抽象化レイヤーよりもはるかに優れていることに同意します。 SQLが設計されていないものに使用されているのは、SQLのせいではありません。
SQLは、いくつかのソースから悪口を付けられます。
1つのDBMS製品に固執する場合、少なくともモデルに固有のスケーラビリティの壁にぶつかるまで、SQL DBは競合製品よりも用途が広く、品質が高いことに間違いなく同意します。しかし、あなたは本当に次のTwitterを書こうとしているのでしょうか、それとも、いくつかの会計データを整理して一貫性を保とうとしているのですか?
SQLに対する批判は、RDBMSに対する批判の代役となることがよくあります。 RDBMSの批評家が理解していないように見えるのは、それらが膨大な種類のコンピューティング問題を非常にうまく解決していること、そして彼らが私たちの生活をより簡単にし、難しくするためにここにいるということです。
彼らがSQL自体を批判することに真剣であるならば、彼らはチュートリアルDやDataphorのような努力を後押しするでしょう。
それほどひどくない。新しい「パラダイム」が登場したときに、以前の信頼性の高いテクノロジーを破壊することは、この業界では残念な傾向です。結局のところ、これらのフレームワークはおそらくSQLを使用してデータベースと通信しているので、どうしてそれが悪いのでしょうか。つまり、「標準」の抽象化レイヤーがあることは、開発者がSQLコードではなくアプリケーションコードに集中できることを意味します。このような標準レイヤーがなければ、システムを開発するたびに軽量なレイヤーを作成することになるでしょうが、これは労力の無駄です。
SQLは、SETベースのデータの管理とクエリ用に設計されています。多くの場合に使用され、Edgeのケースは時々フラストレーションにつながります。
SQLの実際の使用は、SO SQLが問題ではない可能性があるという基本データベース設計の影響を受ける可能性がありますが、設計がそうである可能性があります-そして、悪い設計に関連するレガシーコードを投げると、変更はよりインパクトがあり、インプリメンテーションにコストがかかります(前に戻って「機能している」ものを「修正」したり、目標を達成したりするのは好きではありません)
大工は釘をハンマーでたたき、製材用のこぎりで、滑らかな板を平面で叩くことができます。 ISハンマーと飛行機を使って「のこ引き」することは可能ですが、イライラさせられます。
ひどいとは言わない。一部のタスクには適していません。たとえば、SQLで適切な手続き型コードを書くことはできません。私はかつて、SQLでのセット操作を強制されました。それを理解するのに私はまるまる週末を要した。
SQLはリレーショナル代数のために設計されました-ここでSQLを使用する必要があります。
最近、SQLはひどい言語だとよく耳にします。Sunの下のすべてのフレームワークには、データベース抽象化レイヤーがあらかじめパッケージ化されているようです。
これらのレイヤーは、独自のものをSQL
に変換するだけです。ほとんどのデータベースベンダーにとって、SQL
はエンジンと通信する唯一の方法です。
しかし私の経験では、SQLは多くの場合、データの入力と出力を管理するためのはるかに簡単で、より用途が広く、よりプログラマーフレンドリーな方法です。私が使用したすべての抽象化層は、著しく制限されたアプローチであり、実際の利点はないようです。
…上記で説明した理由。
データベースレイヤーは何もaddしません。それらは単にlimitします。これにより、クエリは疑いなく単純になりますが、効率は向上しません。
定義上、SQL
にないデータベースレイヤーには何もありません。
SQL
をひどいものにしているのはなぜですか。また、なぜデータベース抽象化レイヤーが重要なのですか。
SQL
はいい言語ですが、それを使うには頭の工夫が必要です。
理論的には、SQL
は宣言型です。つまり、取得したいものを宣言し、エンジンがそれを可能な限り最速の方法で提供します。
実際には、正しいクエリ(正しい結果を返すクエリ)を作成する方法はたくさんあります。
オプティマイザは、いくつかの事前定義されたアルゴリズム(そうです、それらは複数です)からレゴ城を構築できますが、新しいアルゴリズムを作成することはできません。それでも、それらを支援するにはSQL
開発者が必要です。
ただし、一部の人々は、オプティマイザが「SQL
エンジンの特定の実装でこのクエリに使用できる最適なプラン」ではなく、「可能な限り最適なプラン」を生成することを期待しています。
そして、誰もが知っているように、コンピュータプログラムが人々の期待に応えられない場合、それは非難されるのはプログラムであり、期待ではありません。
ただし、ほとんどの場合、クエリを再構成することで、可能な限り最良の計画を作成できます。しかし、それが不可能であるときにタスクが存在します。ただし、SQL
の新しい改良が加えられており、これらのケースの数はますます少なくなっています。
ただし、ベンダーが「インデックス範囲の取得」、「rowid
による行の取得」などの関数への低レベルのアクセスを提供した場合、C
コンパイラのように、アセンブリを言語。
最近、私のブログにこれに関する記事を書いています。
フレームワークに含まれているデータベースアブストラクションレイヤーは2つの非常に重要な問題を解決するので、良いことだと思います。
コードを区別します。 SQLを別のレイヤーに配置します。これは一般に非常に薄く、クエリの基本と結果のハンドオフ(標準化された方法で)のみを行う必要があるため、アプリケーションを維持できます。 SQLの煩雑さから解放されます。これは、Web開発者がCSSとJavaScriptを別々のファイルに配置する必要があるのと同じ理由です。回避できる場合は言語を混在させないでください。
多くのプログラマーはSQLの使用がまったく得意ではありません。なんらかの理由で、多数の開発者(特にWeb開発者)は、SQLまたは一般的なRDBMSの使用が非常に非常に悪いようです。彼らは、データベース(および拡張機能によるSQL)を、データを取得するために経験しなければならない厄介な小さな仲介者として扱います。これにより、インデックスのない非常に不十分なデータベース、疑わしい方法でテーブルの上に積み重ねられたテーブル、および非常に不十分なクエリが作成されます。またはさらに悪いことに、それらは一般的すぎる(エキスパートシステム、誰か?)ように試み、データを意味のある方法で合理的に関連付けることができません。
残念ながら、無知、頑固さ、またはその他の特性のために、誰かが問題やツールを解決しようとする方法は、互いに直接対立し、幸運なことにこれを説得しようとすることがあります。このように、データベースアブストラクションレイヤーは、SQLを貧弱な開発者の目から遠ざけるだけでなく、コードを大幅にリファクタリングしやすくするため、データベースアブストラクションレイヤーを一種のセーフティネットと見なしています。すべてのクエリが1か所にあるため。
私は大規模なORM擁護者であり、SQLは非常に有用であると私はまだ信じていますが、(他のものと同じように)それで恐ろしいことを行うことは確かに可能です。 。
私はSQLを、コードの再利用や保守性/リファクタリングを優先事項としない、非常に効率的な言語だと考えています。
したがって、超高速処理が優先されます。そしてそれは許容範囲です。あなたは、私にとってかなりのトレードオフを知っている必要があります。
美的観点から見ると、言語としてOOの概念などがないため、いくつかの点で欠けているように感じます-私にとっては非常に古い学校の手続き型コードのように感じます。しかし、それは特定のことを行うための最速の方法であり、それは強力なニッチです!
SQLは、特定の種類のタスク、特にデータのセットの操作と取得に最適です。
ただし、SQLには、変更と複雑さを管理するためのいくつかの重要なツールがありません(または一部しか実装されていません)。
カプセル化:SQLのカプセル化メカニズムは粗いです。 SQLコードを作成するときは、データの実装に関するすべてを知る必要があります。これは、達成できるabstractionの量を制限します。
ポリモーフィズム:異なるテーブルで同じ操作を実行したい場合は、コードを2回記述する必要があります。 (想像力に富んだビューの使用でこれを軽減できます。)
Visibility control:コードの一部を互いに非表示にしたり、論理的な単位にグループ化したりするための標準のSQLメカニズムがないため、すべてのテーブル、プロシージャなど望ましくない場合でも、他のすべてのユーザーがアクセスできます。
ModularityおよびVersioning
最後に、SQLでCRUD操作を手動でコーディングする(そしてそれを他のアプリケーションにフックするコードを書く)には、繰り返しが多く、エラーが発生しやすくなります。
最新の抽象化レイヤーはこれらすべての機能を提供し、破壊的で反復的な実装の詳細を隠しながら、最も効果的な場所でSQLを使用できるようにします。オブジェクト指向ソフトウェア開発におけるデータアクセスを複雑にする オブジェクトリレーショナルインピーダンスミスマッチ を克服するのに役立つツールを提供します。
IMO、人々がSQLで抱えている問題は、リレーショナルデザインやSQL言語自体とは何の関係もありません。多くの点でビジネスレイヤーやインターフェイスのモデリングとは根本的に異なるデータレイヤーのモデリングの分野に関係しています。プレゼンテーション層でのモデリングの間違いは、一般に、データベースを使用する複数のアプリケーションがあるデータ層よりもはるかに簡単に修正できます。これらの問題は、SOA設計でサービスレイヤーをモデル化するときに発生する問題と同じです。この設計では、サービスの現在のコンシューマーと入出力コントラクトを考慮する必要があります。
SQLは、リレーショナルデータベースモデルと対話するように設計されています。しばらくの間存在していた他のデータモデルがありますが、データレイヤーの設計に関する規律は、使用される理論モデルに関係なく適切に存在するため、開発者がSQLで通常持つ困難は、通常、非リレーショナルを課す試みに関連しています。リレーショナルデータベース製品へのデータモデル。
SQLはSet Theoryに基づいていますが、最近のほとんどの高水準言語はオブジェクト指向です。オブジェクトプログラマーは、通常、オブジェクトを考えるのが好きで、オブジェクトを格納するためのセットベースのツールを使用するために、精神的にシフトする必要があります。一般に、(OOプログラマーにとって)選択した言語でコードをカットし、アプリケーションコードでobject.saveまたはobject.deleteのようなことを行うのではなく、はるかに自然です。 SQLクエリを記述し、データベースを呼び出して同じ結果を達成します。
もちろん、複雑な場合には、SQLの方が使いやすく効率的であるため、両方のタイプのテクノロジーに対応することをお勧めします。
最近よく聞いた?これをNoSqlムーブメントと混同しないでください。私が知る限り、これは主にNoSqlを使用して高スケーラビリティのWebアプリを作成し、SQLが「高スケーラビリティのないWebアプリ」シナリオでは効果的なツールであることを忘れているようです。
抽象化レイヤーのビジネスは、オブジェクト指向コードとテーブルの違いを整理することです。通常、これにより、大量のボイラープレートと2つの間の鈍い遷移コードが書き込まれます。 ORMはこれを自動化し、ビジネスに反対する人々の時間を節約します。
まず、パラメーター化されたクエリを使用するのは簡単で、SQLインジェクション攻撃からユーザーを保護します。この観点から、生のSQLを使用するとリスクが高くなります。つまり、セキュリティの観点から誤解を招きやすくなります。また、データベースにオブジェクト指向の視点を示すことがよくあり、この変換を行う必要がなくなります。
経験豊富なSQLプログラマにとって、悪い面は
他の人にとっては、その理由は
SQLフレームワークの主な目的は、入力を減らすことです。彼らはどういうわけかそうしますが、非常に単純なクエリに対してのみ頻繁に過ぎます。複雑なことをしようとすると、文字列を使用してたくさんタイプしなければなりません。 SQL Alchemyのように可能な限りすべてを処理しようとするフレームワークは、別のプログラミング言語のように巨大になりすぎます。
[26.06.10の更新]最近、私は Django ORMモジュール で作業しました。これは私が目にした中で唯一価値のあるSQLフレームワークです。そして、これは多くのものを扱うことになります。ただし、複雑な集計は少し難しいです。
SQLは、データ操作に最適な言語です。開発者の観点から見ると、データベースを変更してもコンパイル時にコードが壊れないというのが私が気に入らない点です。このため、パフォーマンスを犠牲にしてSQL言語の表現力を犠牲にして、この機能を追加する抽象化を使用します。 、ほとんどのアプリケーションでは、SQLが持っているすべてのものを必要としないからです。
SQLが嫌われるもう1つの理由は、リレーショナルデータベースが原因です。
[〜#〜] cap [〜#〜] 定理が普及する:
共有データシステムにどのような目標が必要ですか?
- 強い整合性:更新がある場合でも、すべてのクライアントに同じビューが表示されます
- 高可用性:障害が発生している場合でも、すべてのクライアントがデータのレプリカを見つけることができます
- パーティション許容度:システムがパーティション化されている場合でも、システムプロパティは保持されます
定理は、同時に3つのCAPプロパティのうち常に2つしか持てないことを規定しています。
リレーショナルデータベースは、強い一貫性とパーティショントレランスに対応します。
したがって、リレーショナルデータベースが特効薬ではないことを理解する人が増え、高可用性により水平方向のスケーリングがより容易になるため、高可用性を支持して拒否する人がますます増えています。 ムーアの法則の限界 に達したため、水平スケーリングが人気を博しているため、スケーリングを行う最良の方法は、マシンを追加することです。
リレーショナルデータベースが拒否されると、SQLも拒否されます。
ここの他のポスターが指摘しているように、SQLには多くの欠陥があります。それでも、「簡略化」は単純化することになっていたものよりも複雑になることが多いため、私は人々が代替手段として提供する多くのツールよりもSQLを使用することを好みます。
私の理論では、SQLは多数の象牙の塔の青いスキーヤーによって発明されたとしています。非手続き構造全体。素晴らしいですね。やりたいことではなく、やりたいことを教えてください。しかし、実際には、多くの場合、手順を示すだけの方が簡単です。多くの場合、これは、完了時に車がどのように機能するかを説明することによって、車のメンテナンス指示を与えようとしているように見えます。はい、「車にもう一度ガロンあたり30マイルを取得し、このようなハミングサウンドで走りたい...うーん...など」と言うことができますが、誰にとっても簡単ではありません"spark plugs"を置き換える)とだけ言ってください。そして、複雑なクエリを非手続き的に表現する方法を理解したとしても、データベースエンジンは非常に非効率的な実行計画を思い付くことがよくあります最初に読み取るテーブルと使用するインデックスを指示する標準化された方法を追加することで、SQLは大幅に改善されると思います。
そしてヌルの扱いは私を狂わせます!はい、理論的には、誰かが「nullが不明を意味する場合、不明な値を既知の値に追加すると、不明な値が得られるはずです。結局のところ、不明な値が何であるかはわかりません。 」理論的には、絶対に本当です。実際には、10,000の顧客がいて、9,999の借金が正確にわかっているが、最後の顧客からの借金について疑問があり、経営陣が「売掛金の総額はいくつですか?」と言っている場合、数学的に正しい答えは「わからない」です。しかし、実際的な答えは「4,327,287.42ドルを計算しますが、1つのアカウントが問題であるため、数値は正確ではありません」です。私は、経営陣が空白の凝視よりも、特定の数ではないにしても、かなり近いものになると確信しています。しかし、SQLはこの数学的に原始的なアプローチを主張しているため、実行するすべての操作で、nullをチェックして特別に処理するために追加のコードを追加する必要があります。
そうは言っても、SQLの上に構築されたいくつかのレイヤーよりもSQLを使用したいので、学習する必要のある別の完全なセットが作成され、最終的にこれがSQLに変換され、場合によっては私はそれを正しく効率的に翻訳するためにそれを信頼することができますが、物事が複雑になるとできないので、追加のレイヤーを知る必要があり、SQLを知る必要があり、それがどのように翻訳されるかを知る必要がありますレイヤーをだましてSQLをだまして正しいことをさせることができます。あー。
SQLはひどい言語ではありません。時々他の人とうまくいかないことがあります。
たとえば、OO言語または別の言語ですべてのエンティティをオブジェクトとして表す必要があるシステムがある場合、これをSQLと組み合わせると、なんらかの抽象化レイヤーなしで、やっかいな作業になる可能性があります。複雑なSQLクエリをOOの世界にマッピングする簡単な方法これらの世界間の緊張を緩和するために、抽象化の追加のレイヤーが挿入されます(たとえば、OR-マッパー)。
•すべてのベンダーは、自社のニーズに合わせてSQL構文を拡張しています。したがって、かなり単純なことを行わない限り、SQLコードは移植できません。
•SQLの構文は直交していません。例:select, insert, update,
and delete
ステートメントはすべて、完全に異なる構文構造を持っています。
SQLをあまり使用していない場合、大きな問題は優れた開発者ツールの不足だと思います。
SQLの経験が豊富な場合は、実行計画を制御できないことに不満を感じることがあります。これは、SQLがベンダーに指定された方法に固有の問題です。 SQLは、基盤となるテクノロジー(非常に強力)を真に活用するために、より堅牢な言語になる必要があると思います。
MySQL、Oracle、MSSQL、PostgreSQL、DB2で機能するデータセットにページ番号を付けるSQLを書いてください。
そうです、標準SQLでは、返される結果の数と開始する行を制限する演算子を定義していません。
私はあなたの点に同意しますが、あなたの質問に答えるために、SQLを「ひどい」ものにする1つのことは、データベースベンダー(SQL Server、Oracleなど)間のT-SQLの完全な標準化の欠如です。完全にポータブル。データベースアブストラクションレイヤーは、パフォーマンスコスト(時には非常に深刻なもの)を伴いますが、この問題を解決します。
純粋なSQLを使用することは、実際にはメンテナンスの地獄です。私にとってORMの最大の利点は、面倒な「DBリファクタリング」手順なしでコードを安全にリファクタリングできることです。 OO言語用の優れた単体テストフレームワークとリファクタリングツールがありますが、たとえば、SQL用のResharperの対応物をまだ見ていません。
それでも、すべてのDALには舞台裏でSQLがあり、データベースに何が起こっているかを理解するにはSQLを知る必要がありますが、優れた抽象化レイヤーでの日常の作業はより簡単になります。
SQLは構文、セマンティクス、および現在の使用法が悪いため、SQLへの愛はありません。説明します:
SQLは仕事を成し遂げる一方で、確かに問題があります...
SQLのユーティリティに関する議論は主に主観的であるが、ビジネスニーズの性質上、より主観的であると私はここのほとんどの投稿に同意します。
Stefan Steineggerが指摘したように、宣言型言語は、希望する方法を指定するのではなく、希望するものを指定するのに適しています。これは、SQLのさまざまな実装が高レベルの観点から適切であることを意味します。つまり、必要なのはデータを取得することだけで、他に何も問題がない場合は、比較的単純なクエリを記述し、SQLの実装を選択することで満足できます。それはあなたにぴったりです。
はるかに「低い」レベルで作業していて、そのすべてを自分で最適化する必要がある場合、それは理想からほど遠いです。抽象化の層をさらに使用すると効果的ですが、実際に実行しようとしているのがクエリを最適化するためのメソッドを指定する場合などは、最適化を試みるときに仲介者を追加するのは少し直観的ではありません。
SQLで私が抱えている最大の問題は、他の「標準化された」言語のようなもので、実際の標準はほとんどありません。 2つの規則が混同されないように、SybaseとMySQLの間でまったく新しい言語を習得する必要がほとんどあります。
SQLは嫌いではありませんが、開発中のSQLの一部として記述したくありません。 DALは、市場投入までの速度を重視するものではありません。実際、コードからの直接クエリよりも高速なDAL実装があるとは、私は考えていません。しかし、DALの目標はabstractです。抽象化にはコストがかかりますが、実装には時間がかかります。
ただし、メリットは非常に大きいです。表現力豊かなクラス、厳密に型指定されたデータセットなどを使用して、コードの周囲にネイティブテストを記述します。C#でジェネリックを使用する純粋なDDD実装である、ソートの「DAL」を使用します。そのため、一般的なリポジトリ、作業単位の実装(コードベースのトランザクション)、および論理的な分離があります。少しの労力でデータセットのモックアウトなどを行うことができ、実際にデータベースの実装より先に開発することができます。このようなフレームワークの構築には先行投資がありましたが、ビジネスロジックがショーの主役ですであることは非常に素晴らしいことです。データをリソースとして消費し、コードでネイティブに使用している言語で処理します。このアプローチの追加の利点は、それが提供する明確な分離です。たとえば、Webページにデータベースクエリが表示されなくなりました。はい、そのページにはデータが必要です。はい、データベースが関係しています。しかし、今は、どこからデータを取得するかに関係なく、コードにアクセスして検索する場所は1つだけです。小さなプロジェクトでは大したことではないかもしれませんが、サイトに数百のページがある場合や、デスクトップアプリケーションに数十のウィンドウがある場合は、本当にそれを評価できます。
私は開発者として、論理的および分析的スキルを使用してビジネスの要件を実装するために雇われました-そして私たちのフレームワークの実装により、私は今より生産的になることができます。私はマネージャーとして、SQLを作成するよりも、論理的および分析的なスキルを使用して問題を解決することを開発者に求めています。開発サイクルの終わりに近づくまで、データベースがなくてもデータベースを使用するアプリケーション全体を構築できるという事実は素晴らしいことです。これは、データベースの専門家をたたくためのものではありません。データベースの実装は、ソリューションよりも複雑な場合があります。 SQL(特に私たちの場合、ビューとストアドプロシージャ)は、コードがサービスとしてデータを消費できる抽象化ポイントです。データチームと開発チームが明確に分かれているショップでは、これにより、データベースの実装と変更を待機している保留パターンに座ることをなくすことができます。開発者はDBAにカーソルを合わせなくても問題のあるドメインに集中でき、DBAは開発者がそれを必要とせずに正しい実装に集中できます今。
ここの多くの投稿は、SQLには「コード最適化」機能がなく、実行計画を制御できないため、SQLは悪いと主張しているようです。
SQLエンジンが得意とするのは、data、実際のcontentsを対象とした、記述された命令の実行計画を作成することです。プログラミングの側面を超えて調べてみると、アプリケーション層の間で渡されるバイトよりもデータの方が多いことがわかります。