web-dev-qa-db-ja.com

SQLが不要であることによってRobert C. Martinはどういう意味ですか?

ロバート・C・マーティンのコンテンツをたくさん読んだり見たりしてきました。ソリッドステートドライブのためにSQLは不要だと私は彼に遭遇しました。これをバックアップするために他のソースを検索すると、ハードドライブとソリッドステートドライブの間のSQLパフォーマンスの違いを説明するランダムな記事がたくさんあります(これは関連していますが、私が調べようとしているものではありません)。

結局、私は彼が何を目指しているのか理解できません。彼はSQLをNo-SQLテクノロジーで置き換えると言っていますか?彼はファイルシステムのファイルにデータを保存すると言っていますか?それとも、SQLi攻撃のために人々にSQL /リレーショナルデータベースの使用をやめてほしいのでしょうか。彼が言おうとしている点を見逃しているのではないかと心配です。

あなたが彼の心から直接読むことができるように私はここにいくつかのリンクを提供します:

  1. ボビーテーブル
  2. クリーンアーキテクチャレクチャー

まず、SQLはシステムから完全に削除する必要があると述べています。

ソリューション。唯一の解決策。システムからSQLを完全に排除することです。 SQLエンジンがない場合、SQLi攻撃はありません。

彼はSQLをAPIで置き換えることについて話していますが、以前の引用と記事の前半で彼が言ったことから、SQLをAPIの後ろに置くことを意味するとは思いません。

フレームワークは問題を処理しません; ...

サイドノート:SQLについて言うと、ロバートはほとんどのリレーショナルデータベースを意味していると確信しています。多分すべてではなく、ほとんど。いずれにせよ、ほとんどの人はとにかくSQLを使用しています。そう...

SQLがデータの永続化に使用されていない場合、何を使用するのでしょうか。

それに答える前に、私も注意する必要があります。 Robertは、ソリッドステートドライブは、データを保持するために使用するツールを変更する必要があることを強調しています。 SørenD.Ptæus's 答えはこれを指摘しています。

「しかし、データの完全性」グループにも対応する必要があります。さらなる調査の結果、ロバートは datomic のようなトランザクションデータベースを使用する必要があると述べています。次に、CRUDはCR(作成と読み取り)に変わり、SQLトランザクションは完全になくなります。データの整合性はもちろん重要です。

これらすべてを網羅する質問は見つかりません。ロバートのガイドラインに一致する代替案を探していると思います。 Datomicは1つですが、それはそれですか?これらのガイドラインに一致する他のオプションは何ですか?そして、それらは実際にソリッドステートドライブでよりよく機能しますか?

45
christo8989

ボブ・マーティンは彼の主張をより明確にするために明らかに誇張しています。しかし、彼のポイントは何ですか?

彼はSQLi攻撃のために人々にSQL /リレーショナルデータベースの使用を止めさせたいだけですか?

私の理解では、そのブログ投稿(最初のリンク)で、マーティンは人々にSQLの使用をやめるように説得しようとしますが、リレーショナルデータベースではありません。これらは 2つの異なるもの

SQLは非常に強力な言語であり、ある程度標準化されています。非常にコンパクトな方法で、読みやすく、理解しやすく、学習しやすい方法で、複雑なクエリとコマンドを作成できます。他のプログラミング言語に依存しないため、Java、C、C++、C#、Python、Ruby、JavaScript、Basic、Go、Perl、PHP、その他のいずれを好むかに関係なく、ほとんどのアプリケーションプログラマーが使用できます。

ただし、この能力にはコストがかかります:安全なSQLクエリ/コマンドを書くことは、安全でないSQLクエリ/コマンドを書くことよりも困難です。安全なAPIを使用すると、「デフォルト」で安全なクエリを簡単に作成できます。安全でない可能性のあるものは、より多くの精神的または少なくともより多くのタイピングの努力を必要とするはずです。それが、マーティンが現在の形でSQLに反対している理由です。

問題は新しいものではなく、リレーショナルデータベースにアクセスするための標準SQLよりも安全なAPIがあります。たとえば、すべてのORマッパーがそのようなAPIを提供しようとしています(通常、他の主要な目的のために設計されていますが)。静的SQLバリアントにより、無害化された入力で動的クエリを作成することが難しくなりますデータ(そして、それは新しい発明ではありません:多くの場合静的SQLを使用する埋め込みSQLは、約30年前のものです)。

残念ながら、私はSQLと同じくらい柔軟性があり、標準化され、成熟し、言語に依存せず、SQL、特に動的SQLほど強力なAPIについては知りません。そのため、前述の問題を解決するための現実的な方法として「SQLを使用しない」というマーティンの提案について、いくつか疑問があります。したがって、彼の記事を正しい方向への思考として読んでください。明日から盲目的にフォローできる「ベストプラクティス」としてではありません。

74
Doc Brown

ボブ・マーティンの意見はそれだけです。一人の男の意見。

プログラマーは、自分が書いているシステムを十分に理解して、そのセキュリティーとパフォーマンスについて妥当な注意を払うことが期待されています。つまり、SQLデータベースと通信している場合、 Bobby Tableswebsite が言うように実行します:入力データをサニタイズします。これは、適切なパフォーマンスを約束するマシンにSQLデータベースを配置することを意味します。これらのことを行うにはよく知られ、よく理解されている方法があり、絶対的なセキュリティや理想的なパフォーマンスを保証するものではありませんが、それ以外のことは何もしません。

SSDを手に入れたのでSQLはもう必要ないという主張は疑わしいものです。高速ハードドライブがまだ存在しないため、SQLは発明されませんでした。これは、データ検索の概念を表現するための業界標準の方法が必要だったために発明されました。リレーショナルデータベースシステムには、速度とセキュリティ以外にも、ビジネスオペレーションに理想的な品質が備わっています。特に、 [〜#〜] acid [〜#〜] です。データの整合性は、少なくとも速度やセキュリティと同じくらい重要です。それがない場合、不良データを保護したり、可能な限り迅速に取得したりする意味は何ですか。

ある人のヒステリーを福音とする前に、ランダムなインターネット記事を読むのではなく、アプリケーションとシステムのセキュリティとパフォーマンスについて、自分の言葉で学ぶことをお勧めします。セキュリティ、パフォーマンス、堅牢なシステム設計には、単に「このテクノロジーを回避する」だけではありません。

キッチンナイフは禁止されていません。何人かの不幸な人が誤って指を切ってしまったためです。

57
Robert Harvey

彼は実際に何を言っているのですか?

彼はSQLをNo-SQLテクノロジーで置き換えると言っていますか?

TL; DR:はい(一種)

あなたがリンクしたものよりも最近の話では、基本的に同じトピックについて彼は言っています: 「データベースは詳細です。なぜデータベースがあるのですか?」

彼は、データベースは回転するディスクからのデータアクセスを容易にするためのものになったと主張していますが、将来的には "[...]ディスクはなくなります" おかげで新しいテクノロジーと彼が「パーシステントRAM」と呼ぶものに、そしてハッシュテーブルやツリーなどのプログラマーが使用する構造を使用してデータを保存する方が簡単になるでしょう。

彼はさらに、新しい競争のためにリレーショナルデータベース全体が大部分はなくなると予測しています。

私がOracleだった場合、私の存在の理由が自分の下から蒸発しているため、私はかなり怖いでしょう。[...]データベースが存在する理由が消えています。

おそらく存続するリレーショナルテーブルがいくつかありますが、現在は健全な競争があります

つまり、彼にとってはSQLインジェクションだけではありませんが、 SQLは本質的にこの点で欠陥があります


著者のメモ:

この投稿のステートメントは、このトピックに関するRobert C. Martinの見解を理解するための引用にすぎず、著者の意見を表すものではありません。より差別化された視点については、 Robert Harveyの回答 を参照してください。

16

SQLは詳細です。詳細の知識は広がってはなりません。

SQLがコードのますます多くの場所で使用されるにつれて、コードはますますそれに依存するようになります。

ますます多くのSQLトリックを学ぶにつれて、SQLを使用してますます多くの問題を解決します。つまり、永続化するために別のAPIに切り替えるには、単に変換するだけではありません。自分が持っていることに気づかなかった問題を解決する必要があります。

データベース間を切り替える場合でも、この問題に直面します。 1つはファンシーウィズバン機能5を提供しているため、さまざまな場所で使用してファンシーウィズバン機能5が独自仕様であることを確認すると、多くの費用がかかるライセンスの問題が発生します。したがって、機能5を使用したあらゆる場所を掘り下げて自分で問題を解決し、後でwhizzbang機能3を使用していることを確認するだけで、多くの作業を行うことになります。

Javaを移植性の高いものにする1つの理由は、CPUの特定の機能が使用できないことです。それらが利用可能であれば、私はそれらを使用します。そして、突然、私のJavaコードは、それらの機能がないために機能しなくなります。データベース機能も同様です。

それを実現せずにあなたの独立性を犠牲にするのは簡単です。 SQLは選択ではありません。 SQLを使用することを決定した場合は、SQLを1か所で使用してください。作ることができない方法でそれを作ります。

SQLにセキュリティの問題があり、永続メモリモデルに移行しているという事実は、SQLが破滅することを意味するものではありません。それは、それが選択であるという点を理解するだけです。あなたがその選択をする権利を維持したいのなら、あなたは仕事をしなければなりません。


80年代とボブおじさんのデータベースの動きにはかなり厄介な歴史があることは注目に値します。管理者がデータベース管理者を強制したとき、彼はすべての問題をフラットファイルシステムで解決しました。この出来事は彼を彼の優れたコンサルティングキャリアに押し上げました。 (彼は彼の初期のきれいな本の1つでこの話を語っていますが、忘れてください)彼はDBなしで問題を解決する方法を知っており、それらを使用するように振る舞う人に対する忍耐力はほとんどありません。

彼はまた、顧客が要求したギリギリまでDBをアプリケーションに追加することを延期し、オプション機能として1日で追加したという話もしています。私の推測では、彼は私たちのほとんどが中毒としてDBを使用する方法だと思います。彼は私たちに習慣を蹴る方法を見せようとしています。

11
candied_orange

あなたの最初の引用からの引用は(私の強調)です、

ソリューション。唯一の解決策。システムからSQLを完全に削除する。 SQLエンジンがない場合、SQLi攻撃はありません。

SQLを置き換えるものは何ですか?もちろんAPI!また、テキスト言語を使用するAPIではありません。代わりに、適切なデータ構造と関数呼び出しを使用して必要なデータにアクセスするAPI。

アプリケーションプログラマにSQLの使用を許可することに反対しています。

推奨される修正は、代わりにAPIを使用できるようにすることです。これはSQLではなく、インジェクションを許可しません。

IMO、そのようなAPIの例には次のものがあります。

  • http://bobby-tables.com/csharp は、C#プログラマがADO.NET APIを使用できることを示唆しています。

    ADO.NETは幅広いまたは深い(つまり、強力または汎用の)APIであるため、これは完璧な例ではありません。を使用すると、ユーザーはraw(またはraw-ish)を入力できますSQL。

  • 一部のSQL開発者またはデータベース管理者は、データベースは、(限られた数の巧妙に記述された) ストアドプロシージャ を介したアクセスのみを許可するように構成する必要があり、アプリケーション開発者は、自分の(危険な)SQLクエリ

  • 「システムからSQLを削除する」もう1つの方法は、=otherシステムにデータベース(SQLを公開)を置き、REST APIなど。

したがって、IMO、全体的なソリューションまたはシステムは引き続きデータベースを使用できます(特に、データベースエンジンが有用なACIDプロパティを実装し、適切にスケーリングしている場合など)、それなしで実行することや、アプリケーション固有のもの)。

データベースのSQL APIがアプリケーション開発者から隠されていて、他のAPI(たとえば、ADO、おそらくORM、Webサービスなど)の背後にある場合、暴言の要件は満たされます。

より一般的には、アプリケーション固有のDAL(「データアクセスレイヤー」または「データベースアブストラクションレイヤー」)を持つことを意味すると思います。 DALは、データがどのようにどこに保存およびフェッチされるかという詳細からアプリケーションを隔離します。 DALは、SQLデータベースを使用して実装されている場合とされていない場合があります。

5
ChrisW

誰もがセキュリティの観点から、またはSQLレンズでこの質問に答えているようです。

Robert Martinの講義を見たとき、彼はプログラマーとして、特定のプログラムに最適なさまざまなデータ構造を使用していると語りました。したがって、すべてのデータを表形式の構造で普遍的に格納するのではなく、データをハッシュテーブルやツリーなどに格納して、データを取得してプログラムに直接ジャンプできるようにする必要があります。

私は彼のメッセージを、永続的なストレージに関する現在の前提を少しの間捨てて、古くからあるSQL表形式以外の将来の可能性を検討するべきだとだけ解釈した。 SSDはソリューションの候補ですが、唯一のものではありません。

3
Keenan

回答

彼は、SQLi攻撃のために人々にSQL /リレーショナルデータベースの使用を停止させたいだけですか?

'Bobby Tables'の記事は、これ、それ自体がSQLを使用しない理由であることを示唆しているようです:

ソリューション。唯一の解決策。システムからSQLを完全に排除することです。 SQLエンジンがない場合、SQLi攻撃はありません。

彼は他の場所で議論する他の理由があるかもしれません。私は彼のものをあまり読んでいないので、私にはわかりません。

余談

この部分は実際には答えではありませんが、SQLの価値についての質問ははるかに興味深いと思います(他の人もそうですが)。

SQLの使用経験は豊富ですが、SQLの長所と短所についてはかなり理解していると思います。私の個人的な感想は、それは使いすぎて乱用されているということですが、私たちがそれを使用してはならないという考えはちょっとばかげています。 「SQLを常に使用する」または「SQLを使用しない」を選択する必要があるという考えは、誤った二分法です。

SQLインジェクションがSQLを使用しないことの議論である限り、それは笑えることです。これは、かなり単純なソリューションでよく理解されている問題です。この議論の問題は、SQLiだけが存在する脆弱性ではないということです。 JSON APIを使用すると安全であると思われる場合は、大きな驚きがあります。

私はすべての開発者が このビデオを見る というタイトルのはずだと思います。

じっくり観察する時間や傾向がない場合は、ここに要点があります。JSONの逆シリアル化ライブラリの多くに、リモートでコードが実行される脆弱性があります。 XMLを使用している場合は、さらに心配する必要があります。アーキテクチャからSQLを禁止しても、システムが安全になるわけではありません。

2
JimmyJames

マーティンの問題は、ユーザー入力から動的SQLを直接作成するプログラマーにあるようです。

sprintf( query, "select foo from bar where %s;", user_input );

これは絶対に胸焼けのレシピです(つまり Bobby Tables ストリップ)。そのようなコードを本番システムに配置するプログラマーなら誰でもpaddlin 'に値します。

準備されたステートメントを使用し、入力を適切にサニタイズすることで、問題を軽減することができます(完全に排除しない場合でも)。プログラマーがクエリ文字列を直接作成しないようにSQLをAPIの背後に隠すことができれば、はるかに優れています(これはMartinの主張の一部です)。

しかし、SQLを完全に取り除くことに関しては、それは実用的でも望ましいとも思いません。リレーショナルモデルは便利です。そもそもそれがモデルが存在する理由であり、SQLはおそらくリレーショナルモデルを操作するための最良のインターフェースです。

いつものように、それは仕事に適したツールを使用することの問題です。ショッピングカートアプリが完全なリレーショナルモデルを必要としない場合、リレーショナルモデルを使用しないでください(つまり、SQLを使用する必要がないことを意味します)。リレーショナルモデルが必要な場合は、ほとんどの場合SQLを使用します。

2
John Bode

私は短い声明だけに取り組みたいです:

それとも、SQLi攻撃のためにSQL /リレーショナルデータベースの使用をやめてほしいのでしょうか。

いいえ。それは間違った仮定です。自動車事故で亡くなった人々の責任であるからといって、車の使用をやめなければならないというわけではありません。同様に、SQL /リレーショナルデータベース(またはRDBMSなど、このコンテキストの他のすべてのもの)は、攻撃者がWebアプリケーションで実行できる悪意のあるSQLペイロードの責任を負いません。この目的のために SQLインジェクション防止のチートシート があるため、作成者がそれを意味しなかったと確信しています。

2

実際、彼はデータベースとSQLを使用するのではなく、かなり明示的に使用します。最初のリファレンスはよく知られた問題であり、2番目のリファレンスは暴言のように聞こえます。ただし、SQLを使用せずにデータベースを使用する十分な理由があると解釈しています。私の観点からは、これは妥当なアドバイスでさえありません。

残念ながら、彼が使用している例はよく知られている例であり、よく知られている解決策を彼が指摘しています。これは通常、プログラマーが自分のしていることを理解していないときに発生します。たとえば、次のようなSQLを含む文字列を作成します。

    my $sql="select a from b where a=$ui_val;";
    prepare($sql)
    execute($sql)

とは対照的に

    my $sql="select a from b where a=?;";
    prepare($sql)
    execute($sql,$ui_val);

これは、Ruby on Railsコードの例です。彼が提供するRailsコードは、安全と非安全を混同します。多くのORMがSQLの下にあるものを隠しているように、SQLを構築して実行するインターフェースを扱っていることがよくあります。これは、APIが何をしているかにほとんど似ていませんか? ?

最初の参照の私の解釈は、よく知られている解決策があるよく知られている問題を置き換える必要があることを彼が示唆しているというものです。

また、これが正しく行われるとコードの記述が容易になり、読みやすくなりますが、適切に行われると、実際には記述が難しく読みにくくなる可能性があることについては言及していません。さらに、SQLは非常に読みやすく、一般的にSQLが期待することを実行することについては触れていません。

彼は部分的に正しいですが、最終的には無限に大きくて高速なメモリと無限に速いプロセッサができます。コンピューティングを制約する現在の物理学から抜け出すまで、彼は正しくありません。

はい、回転ディスクは過去のものであり、現在SSDを使用しています。ディスクはデータ転送あたり約10ミリ秒で動作し、SSDは約0.5ミリ秒(500マイクロ秒)のデータアクセス時間で動作します。 RAMは100ナノ秒程度であり、プロセッサは数百ピコ秒のオーダで動作します。これがデータベースが必要な理由の中心です。データベースは、回転ディスクまたはメインメモリを備えたSSD SSDの登場は、データベースの必要性を排除していません。

2
Robert Baron

リンクする2つのソースは異なるメッセージを伝えます。

ブログの投稿によると、データアクセスロジックは実行時にテキストとして存在してはならず、信頼できないユーザー入力と混同しないようにしてください。つまり、ブログの投稿では、文字列を連結してクエリを書くことを非難しています。

講義は違います。最初の違いは口調にあります。講義は推測し、疑問を投げかけますが、非難しません。彼はデータベースが悪だとは言いませんが、データベースのない永続性を想像するように私たちに挑戦します。彼は、リレーショナルデータベースが普及してから30年間で多くのことが変化したと主張し、永続化テクノロジの選択におそらく影響を与える可能性のある2つの点を強調しています。

  • 収納スペースが約100万倍になりました-同等の価格で!その結果、ストレージを節約する必要性が減り、特に、削除する必要がなくなりました。追加専用ストレージを使用すると、読み取りロックが不要になるため、並行性制御を簡略化できます。これにより、トランザクションが不要になります。
  • ほとんどのデータセットがRAMに収まるようになり、読み取りレイテンシが大幅に減少したため、アクセス時間が減少しました。

これらの変化した状況は、最適な持続性テクノロジーを変化させますか?興味深いことに、ボブおじさんは言っていません-おそらく彼はすべてのプログラムにとって正しい答えはないと感じているからです。だからこそ、私たちの永続化技術の選択を石版に納め、仲間に知恵として伝えるのではなく、細部として扱うよう警告しています。

代替案はありますか?

文字列なしでデータアクセスロジックを作成することは完全に可能です。 Java土地では、 QueryDSL を使用できます。ここで、クエリはデータベーススキーマから生成されたタイプセーフな流れるAPIを使用して記述されます。このようなクエリは次のようになります。

JPAQuery<?> query = new JPAQuery<Void>(entityManager);
Customer bob = query.select(customer)
  .from(customer)
  .where(customer.firstName.eq("Bob"))
  .fetchOne();

ご覧のとおり、クエリロジックは文字列として表現されておらず、信頼できるクエリの構造と信頼できないパラメータを明確に分離しています(もちろん、QueryDSLはパラメータをクエリテキストに含めず、準備されたステートメントを使用してクエリを分離しますJDBCレベルでのパラメータについて)。 QueryDSLでSQLインジェクションを実現するには、独自のパーサーを記述して文字列を解析し、それを構文ツリーに変換する必要があります。それを行ったとしても、select ... into fileのような厄介なものに対するサポートはおそらく追加しません。つまり、QueryDSLはSQLインジェクションを不可能にし、プログラマの生産性を向上させ、リファクタリングの安全性を高めます。 実行中のギャグ を生成するのに十分長く存在し、開発者の生産性を向上させるWebアプリケーションセキュリティへの最大のリスクを防止しましたか?クエリを文字列として記述していると、間違いを犯すことになります。

リレーショナルデータベースの代わりとして、postgresの multi version concurrency control が、まさにそのような追加専用のデータ構造であることを知っているのは不思議です。 イベントストア 、および イベントソースパターン は一般的に、現在の状態をRAMに保持するという概念にもよく適合します。

1
meriton