web-dev-qa-db-ja.com

MySQLストアドプロシージャはそれらを使用するかどうか

私たちは新しいプロジェクトの始まりであり、MySQLでストアドプロシージャを使用すべきかどうか本当に疑問に思っています。

ストアドプロシージャは、ビジネスモデルエンティティの挿入と更新にのみ使用します。モデルエンティティを表すいくつかのテーブルがあり、それらのストアドプロシージャの挿入/更新で抽象化します。

一方、MySQLではなくPHPでモデルレイヤーから挿入および更新を呼び出すことができます。

あなたの経験では、どちらが最良のオプションですか?両方のアプローチの長所と短所。高性能の点でどちらが最も速いですか?

PS:これは、ほとんどが読み取り可能なWebプロジェクトであり、高性能が最も重要な要件です。

61
Emilio Nicolás

実際のプログラミング言語コードとは異なり、彼らは:

  • 移植性がありません(dbごとに独自のバージョンのPL/SQLがあります。sameデータベースの異なるバージョンには互換性がない場合があります-私はそれを見ました!)
  • 簡単にテストできません-テストするにはreal(dev)データベースインスタンスが必要です。したがって、ビルドの一部としてコードを単体テストすることは事実上不可能です。
  • 簡単に更新/解放できない-それらをドロップ/作成する必要があります。つまり、modify本番データベースをリリースするために
  • ライブラリをサポートしていない(他の誰かが持っているときにコードを書く理由)
  • 他のテクノロジーと簡単に統合できない(それらからWebサービスを呼び出してみてください)
  • fortranと同じくらい原始的な言語を使用しているため、有用なコーディングを行うには洗練されず面倒であるため、ビジネスロジックを表現することは困難です。
  • デバッグ/トレース/メッセージロギングなどを提供しません(一部のデータベースはこれをサポートしている可能性があります-まだ見ていません)
  • まともなIDEが構文と他の既存の手順へのリンクを支援するために欠けている(EclipseがJavaで行うように)
  • それらのコーディングに熟練した人々は、アプリコーダーよりも希少で高価です
  • それらの「高性能」は神話です。データベースサーバーで実行されるため、通常はincrease dbサーバーの負荷です。したがって、通常はreduce最大トランザクションスループット
  • 定数を効率的に共有できない(通常、テーブルを作成し、プロシージャ内から検索することで解決されます-非常に非効率的)
  • 等.

非常にデータベース固有のアクション(データベースの整合性を維持するためのトランザクション内アクションなど)がある場合、またはプロシージャを非常にアトミックかつシンプルに保つ場合は、おそらくそれらを検討することができます。

「高性能」を事前に指定する場合は注意が必要です。多くの場合、良いデザインを犠牲にして悪い選択につながり、あなたが思っているよりもずっと早く噛みつきます。

自分の危険でストアドプロシージャを使用します(そこにいて、二度と戻りたくない人から)。私の推奨は、ペストのようにそれらを避けることです。

69
Bohemian

プログラミングコードとは異なり、彼らは:

  • sQLインジェクション攻撃をほぼ不可能にします(あなたが
    動的の構築と実行
    プロシージャ内からのSQL)
  • コールアウトの一部として [〜#〜] ipc [〜#〜] を介して送信する必要があるデータがはるかに少ない
  • データベースのキャッシュプランと結果セットをはるかに優れたものにします(これは、内部キャッシュ構造のため、MySQLではあまり効果的ではありません)
  • 分離して簡単にテスト可能です(つまり、JUnitテストの一部としてではありません)
  • プロシージャ名の背後に抽象化されたdb固有の機能を使用できるという意味で移植性があります(コードでは、一般的なSQLタイプのものにこだわっています)
  • コードから呼び出されるSQLよりも遅くなることはほとんどありません

しかし、ボヘミアンが言うように、多くの短所もあります(これは別の観点を提供するためです)。最適なものを決める前に、おそらくベンチマークを行う必要があります。

29
davek

パフォーマンスに関しては、将来のMySQLバージョンでは実際にパフォーマンスが向上する可能性になります(SQL ServerまたはOracleでは、本当におもしろいです!)。しかし、それ以外のすべての場合...彼らは完全に競争を爆破します。要約します:

  • セキュリティ:アプリにEXECUTE権限のみを付与できます。すべて問題ありません。 SPは、select select ...を挿入しますが、いかなる種類のリークも発生する可能性はありません。モデルをグローバルに制御し、データセキュリティを強化することを意味します。

  • セキュリティ2:まれであることは知っていますが、サーバーからphpコードが漏れることがあります(つまり、一般に公開されます)。クエリが含まれている場合、潜在的な攻撃者はモデルを知っています。これはかなり奇妙ですが、とにかく合図したかったです

  • タスクフォース:はい、効率的なSQL SPを作成するには特定のリソースが必要であり、場合によってはより高価になります。ただし、クエリをクライアントに統合しているという理由だけでこれらのリソースが必要ないと思う場合は、深刻な問題が発生します。 Web開発の類似性について言及します。プログラマーはビジネス層のプログラミングに集中できる一方で、デザイナーは独自のテクノロジーに取り組むことができるため、ビューを他のビューから分離するのは良いことです。

  • ビジネスレイヤーのカプセル化:ストアドプロシージャを使用することで、属するビジネスであるデータベースを完全に分離します。

  • すばやくテスト可能:シェルの下の1つのコマンドラインとコードがテストされます。

  • クライアントテクノロジーからの独立性:明日、PHPから他の何かに切り替えたい場合は、問題ありません。 OK、これらのSQLを別のファイルに保存するだけでもうまくいきます、そうです。また、SQLエンジンの切り替えを決定した場合、多くの作業が必要になるというコメントの良い点です。とにかくそれをする正当な理由が必要です。なぜなら、大規模なプロジェクトや大企業の場合、それはめったに起こらないからです(主にコストと人事管理のため)

  • アジャイル3+層開発の実施:データベースがクライアントコードと同じサーバー上にない場合、異なるサーバーがありますが、データベース用は1つだけです。その場合、SQL関連のコードを変更する必要がある場合、PHPサーバーをアップグレードする必要はありません。

わかりました、それは私が主題について言わなければならなかった最も重要なことだと思います。私は両方のスピリット(SP対クライアント)で開発しました。本当に、SPスタイルのスタイルが大好きです。MySQLに本当のIDE今はちょっと お尻の痛み 限られた。

14
Sebas

ストアドプロシージャは、クエリを整理し、一度にバッチを実行できるため、使用すると便利です。ストアドプロシージャは、実行ごとにコンパイルされるクエリとは異なり、プリコンパイルされているため、通常は実行が高速です。これは、データベースがリモートサーバー上にある場合に大きな影響があります。クエリがPHPスクリプト内にある場合、アプリケーションとデータベースサーバー間に複数の通信があります-クエリは送信、実行され、結果が返されます。ただし、ストアドプロシージャを使用する場合は、大きな複雑なクエリの代わりに小さなCALLステートメントを送信する必要があります。

ストアドプロシージャには独自の言語と構文があるため、ストアドプロシージャのプログラミングに適応するには時間がかかる場合があります。しかし、慣れてしまえば、コードが本当にきれいであることがわかります。

パフォーマンスの観点から、ストアドプロシージャを使用してもしなくても、大幅な改善はないかもしれません。

7
Abhay

私の考えは質問に直接関係していない可能性がありますが、私は私の意見をお知らせします。

多くの問題と同様に、ストアドプロシージャまたはアプリケーションレイヤー駆動型ソリューションの使用に関する返信は、全体的な努力を促す質問に依存しています。

  • 取得したいもの。

バッチ操作またはオンライン操作のどちらを試みていますか?それらは完全にトランザクションですか?これらの操作はどの程度繰り返しますか?データベースの待機中のワークロードはどれくらい重いですか?

  • あなたがそれを得るために持っているもの。

どんな種類のデータベース技術を持っていますか?どのようなインフラストラクチャですか?あなたのチームはデータベーステクノロジーの完全なトレーニングを受けていますか?あなたのチームはデータベースに依存しないソリューションを構築する能力がありますか?

  • それを得るための時間。

それについての秘密はありません。

  • 建築。

ソリューションを複数の場所に配布する必要がありますか?リモート通信を使用するにはソリューションが必要ですか?ソリューションは複数のデータベースサーバーで機能していますか、それともクラスターベースのアーキテクチャを使用していますか?

  • メンテナンス。

アプリケーションを変更するにはどれくらい必要ですか?ソリューションを維持するために特別に訓練された個人はいますか?

  • 変更管理。

あなたのデータベース技術は、短期、中期、長期で変化するでしょうか?ソリューションを頻繁に移行する必要があると思われますか?

  • 費用

1つまたは別の戦略を使用してそのソリューションを実装するにはどれくらいの費用がかかりますか?

これらのポイントの全体が答えを導きます。そのため、戦略を使用するかどうかについて決定するときは、この各点に注意する必要があります。ストアドプロシージャの使用は、アプリケーション層で管理されたクエリよりも優れている場合があり、クエリを実行してアプリケーション層ベースのソリューションを使用するのが最適な場合もあります。

ストアドプロシージャの使用は、次の場合により適切になる傾向があります。

  1. データベーステクノロジーは、短期間で変更するためのものではありません。
  2. データベーステクノロジは、並列化された操作、テーブルパーティション、またはワークロードを複数のプロセッサ、メモリ、リソース(クラスタリング、グリッド)に分割するその他の戦略を処理できます。
  3. データベーステクノロジは、ストアドプロシージャ定義言語と完全に統合されています。つまり、サポートはデータベースエンジン内にあります。
  4. 結果を得るために手続き型言語(第3世代言語)を使用することを恐れない開発チームがいます。
  5. 実現したい操作は、データベース内に組み込まれているか、サポートされています(XMLデータへのエクスポート、トリガー、スケジュールされた操作などによるデータの整合性と一貫性の管理)。
  6. 移植性は重要な問題ではなく、技術の変更が短時間で組織に反映されることはありませんが、それは望ましくありません。一般的に、移植性は、アプリケーション駆動型およびレイヤー指向の開発者にとってはマイルストーンのように見えます。私の観点からすると、アプリケーションをいくつかのプラットフォームにデプロイする必要がない場合、移植性は問題ではありません。テクノロジーを変更する理由がない場合、または組織データをすべて移行する労力が変更を行うことの利点。データベースから得られるパフォーマンスと価値を失う可能性があるアプリケーション層駆動アプローチ(移植性)を使用することで勝つことができるもの?)。
  7. パフォーマンスが問題です。まず、いくつかのケースでは、単一のストアドプロシージャコールを使用することで、別のアプリケーションからのデータに対する複数のリクエストよりも良い結果を得ることができます。さらに、実行する必要のあるいくつかの特性はデータベースに組み込まれている場合があり、ワークロードの観点からその使用はより安価です。アプリケーション層駆動のソリューションを使用する場合、データベース接続の作成、データベースへの呼び出し、ネットワークトラフィック、データラッピングに関連するコストを考慮する必要があります(つまり、Javaまたは.NETでは、JDBC/ADO.NET呼び出しを使用すると、データベースデータを表すオブジェクトにデータをラップする必要があるため、暗黙的なコストが発生します。そのため、インスタンス化には、データの取得時の処理、メモリ、ネットワーク外に出ます)。

アプリケーション層駆動型ソリューションの使用は、次の場合により適切になる傾向があります。

  1. 移植性は重要な問題です。
  2. アプリケーションは、1つまたは少数のデータベースリポジトリのみを持つ複数の場所に展開されます。
  3. アプリケーションは、ビジネス指向の重いルールを使用します。このルールは、基盤となるデータベーステクノロジーにとらわれない必要があります。
  4. 市場の傾向と予算に基づいてテクノロジープロバイダーを変更することを念頭に置いてください。
  5. データベースは、データベースを呼び出すストアドプロシージャ言語と完全には統合されていません。
  6. データベースの機能は制限されており、要件はデータベーステクノロジーで達成できる範囲を超えています。
  7. アプリケーションは、外部呼び出しに固有のペナルティをサポートでき、ビジネス固有のルールによりトランザクションベースであり、ユーザーのビジネスモデルにデータベースモデルを抽象化する必要があります。
  8. データベース操作の並列化は重要ではありません。さらに、データベースには並列化機能がありません。
  9. データベーステクノロジーに関する十分なトレーニングを受けていない開発チームがあり、アプリケーション駆動型ベースのテクノロジーを使用することで生産性が向上しています。

これが何を使うのが良いのか自分自身に尋ねる人に役立つことを願っています。

5
Enyix Mexico

ストアドプロシージャを使用しないことをお勧めします。

  • MySQLの言語は非常にくだらない
  • 配列、リスト、またはその他の種類のデータ構造をストアドプロシージャに送信する方法はありません。
  • ストアドプロシージャはeverインターフェースを変更できません。 MySQLは名前付きパラメーターもオプションのパラメーターも許可しません
  • アプリケーションの新しいバージョンのデプロイがより複雑になります-10xのアプリケーションサーバーと2つのデータベースがあるとします。最初にどちらを更新しますか?
  • すべての開発者は、ストアドプロシージャ言語を学習し、理解する必要があります-これは非常にくだらないことです(前述したとおり)

代わりに、レイヤー/ライブラリを作成し、そこにすべてのクエリを配置することをお勧めします

あなたはできる

  • このライブラリを更新し、アプリとともにアプリサーバーに送信します
  • 配列、構造などの豊富なデータ型を渡す
  • ストアドプロシージャの代わりに、このライブラリを単体テストします。

パフォーマンスについて:

  • ストアドプロシージャを使用すると、アプリケーション開発者のパフォーマンスが低下します。これが重要なことです。
  • 複雑なストアドプロシージャ内でパフォーマンスの問題を特定することは非常に困難です(単純なクエリの方がはるかに簡単です)
  • (CLIENT_MULTI_STATEMENTSフラグが有効になっている場合)クエリバッチを単一のチャンクで送信できます(つまり、ストアドプロシージャなしでは遅延が発生しません)。
  • 一般に、アプリケーション側のコードは、データベース側のコードよりも優れた拡張性を備えています
3
MarkR

データベースが複雑であり、応答を伴うフォーラムタイプではないが、真のウェアハウジングSPが確実に利益をもたらします。すべてのビジネスロジックをそこに置くことができ、1人の開発者が気にしない、彼らはあなたのSPを呼び出すだけです。15を超えるテーブルを結合するのは面白くなく、新しい開発者に説明することはできません。

また、開発者はDBにアクセスできません。データベース設計者とメンテナーに任せてください。また、テーブル構造が変更されると判断した場合、これをインターフェイスの背後に隠すことができます。 n層、覚えていますか??

高性能なリレーショナルDBは、MySQL InnoDBが遅い場合でも、一緒に動くものではありません。MyISAMは今から窓の外に捨てられるべきです。 Webアプリでパフォーマンスが必要な場合は、適切なキャッシュ、memcacheなどが必要です。

あなたの場合、あなたが「Web」に言及したので、ストアドプロシージャは使用しません。データウェアハウスであれば、間違いなく検討します(倉庫にはSPを使用します)。

ヒント:Webプロジェクトについて述べたので、nosqlのような解決策についてはどうでしょうか?また、高速DBが必要です。PostgreSQLを使用してみませんか? (ここで主張しようとしています...)

2
R. van Twisk

私はMySqlを使用していましたが、SQLの理解はせいぜい貧弱でした.SQL Serverの使用にはかなりの時間を費やしました。データレイヤーとアプリケーションレイヤーの明確な分離があり、現在は0.5テラバイトのサーバーを管理しています。

ORMを使用しないと、ストアドプロシージャを使用すると開発が非常に速くなり、非常に時間がかかるため、不満を感じることがあります。私たちの仕事の多くは、ORMを使用することで高速化できたと思います。

アプリケーションがクリティカルマスに達すると、ORMのパフォーマンスが低下し、適切に記述されたストアドプロシージャにより、結果がより速く得られます。

パフォーマンスの例として、アプリケーションで10種類のデータを収集し、それをXMLに変換します。これをストアドプロシージャで処理し、10回ではなくデータベースを1回呼び出します。

SQLはデータのセットを扱うのが本当に得意です、私がイライラすることの1つは、誰かが生の形式でSQLからデータを取得し、アプリケーションコードを使用して結果をループし、それらをフォーマットし、グループ化することです、これは本当に悪い習慣です。

私のアドバイスは、SQLを十分に学び理解することです。そうすれば、アプリケーションは本当に恩恵を受けるでしょう。

2
Charles Bryant

人々を混乱させるためにここにたくさんの情報があります、ソフトウェア開発は進化的です。 20年前にやったことは、今ではベストプラクティスではありません。昔のクライアントサーバーでは、SP以外の夢はありませんでした。

あなたが大規模な組織の場合、マルチティアを使用し、おそらくSPを使用しますが、専任のチームがそれらを整理するので、あなたはそれらをほとんど気にしません。

反対に、ビジネス要件を充足するWebアプリソリューションをすばやくノックアップしようとすると、ページとSQLクエリをノックアップするために開発者(私にリモート)を任せてDBを定義するのは非常に高速でした構造。

しかし、複雑さが増しているため、APIを提供する簡単な方法がなければ、SPを使用してビジネスロジックを含めることを考えています。私はロジックを構築し、オフショア開発者がフロントエンドを構築するためのシンプルな結果セットを提供できるため、これはうまく機能し、賢明だと思います。

私のソフトウェアが驚異的な成功を収めた場合、懸念がさらに分離され、n teirのさまざまな実装が行われますが、現時点ではSPは完璧です。

あなたが利用できるすべてのツールセットを知っている必要があり、それらを一致させるのが賢明です。最初からエンタープライズシステムを構築する場合を除き、高速でシンプルな方法が最適です。

1
Richard

DB固有のストアドプロシージャから離れることをお勧めします。

私は彼らが突然DBプラットフォームを切り替えたい多くのプロジェクトを経験してきましたが、SP内のコードは通常あまり移植性がなく、余分な作業とエラーの可能性があります。

ストアドプロシージャ開発では、開発者がSQLエンジンに直接アクセスする必要もあります。通常の接続は、プロジェクト内の誰でもコードアクセスのみで変更できます。

モデル/レイヤー/層のアイデアについて:はい、それを守ります。

  • Webサイト呼び出しビジネス層(BL)
  • BLはデータ層(DL)を呼び出します
  • DLは、あらゆるストレージ(SQL、XML、Webサービス、ソケット、テキストファイルなど)を呼び出します

これにより、階層間のロジックレベルを維持できます。 IFおよびONLY IF DL呼び出しは非常に遅いようです。ストアドプロシージャをいじり始めることができますが、突然DBを転送する必要がある場合は、元の非SPコードをどこかに維持できます。まったく新しいプラットフォームへ。ビジネスにおけるすべてのクラウドホスティングを使用して、次のDBプラットフォームになるものを知ることはできません...

同じ理由で、Amazon AWSを注意深く監視しています。

1
BerggreenDK

データベースに保存されたクエリについて、多くの誤った情報が流れていると思います。

データ操作のために多くの静的クエリを実行している場合は、MySQLストアドプロシージャの使用をお勧めします。特に、あるテーブルから別のテーブルに物を移動する場合(つまり、何らかの理由でライブテーブルから履歴テーブルに移動する場合)。もちろん、変更のログを個別に保存する必要があるという欠点があります(理論的には、DBAが更新するストアドプロシージャへの変更のみを保持するテーブルを作成できます)。データベースとインターフェイスする多くの異なるアプリケーションがある場合、特にC#で記述されたデスクトッププログラムとPHPのWebプログラムがある場合、プラットフォームに依存しないため、一部のプロシージャをデータベースに保存する方が有益な場合があります。

このWebサイトには、役に立つと思われる興味深い情報が掲載されています。

https://www.sitepoint.com/stored-procedures-mysql-php/

いつものように、最初にサンドボックスに組み込み、テストします。

0
Dave Babler