分散データベースの観点から見たストアド プロシージャ

ストアド プロシージャは非常に優れていますが、これをうまく使用できない人はスキルが低く、反論を受け付けません。私もこのアイデアを持っていましたが、分散データベースの場合は、ストアド プロシージャをあまり使用しない、または使用しないことを好みます。

1 C/S時代から来た

C/S アーキテクチャ時代の終わりに最も人気のある開発キットは、PowerBuilder データベースと Sybase データベースです。

  • PowerBuilder ビジュアル開発ツール (VB と同様)。開発されたプログラムはユーザーの PC 端末上で実行され、ドライバーを介してリモート データベースに接続します。
  • 当時、Sybase は Oracle とデータベースの主導権を争っており、SQL Server とも深い関係にあり、両者はアーキテクチャと言語が非常に似ていました。

この C/S アーキテクチャでは、データベースはデータの保存と計算機能を担うだけでなく、アプリケーション サーバー (アプリケーション サーバー) のほとんどの機能を担うデータベースに相当する、重いビジネス ロジックも実行します。これらのビジネス ロジックの技術的キャリアはストアド プロシージャです。したがって、Sybase であっても Oracle であっても、ストアド プロシージャは非常に強力です。

2 つのトリガーは破棄されます

B/S に入ると、データベースに対するみんなの理解が変わり、アプリケーション サーバーがサーバーの主要なビジネス ロジックを担います。それでもストアド プロシージャを使用しますか? 今日と同じ問題。当時の主流の見方は、ストアド プロシージャには依然として価値があるが、その兄弟トリガーは完全に放棄されたというものでした。

トリガーはストアド プロシージャのようなカスタム関数ですが、次のとおりです。

  • これは明示的に呼び出されるのではなく、データテーブルの操作時、つまり挿入、更新、削除の実行時に受動的にトリガーされます。
  • トリガーのタイミングが操作の前か後か、つまり前後のセマンティクスを選択することもできます。

強力で、ちょっとしたイベント指向のプログラミングのように聞こえます。しかし、トリガー ロジックを維持した後、これが大きな落とし穴であることがわかりました。ビジネスが発展し、変化するにつれて、トリガーのロジックはますます複雑になります。誰かがトリガーのロジックで別のテーブルを操作し、そのテーブルには他のテーブルに関係する他のトリガーが存在し、スカイネットを形成します。小さな一歩が連鎖反応を起こし、大惨事となります。したがって、トリガーは歴史の舞台から退いた。(制限が多すぎて悪用につながるのではないかと今でも感じています)

3 ストアド プロシージャの利点

通話は明瞭で、トリガーの問題もありません。利点は明白で、ロジックはデータベース内で実行され、ネットワーク送信データのオーバーヘッドがないため、データ集約型の操作を実行する際のパフォーマンス上の利点が顕著になります。

その際、AはBに影響を与え、BはCに影響を与えるというように、機能を開発して事業体間の影響関係を追跡する必要がありました。この機能は、A を入力として使用して、B と C の両方を見つけることです。もちろん、影響関係は 3 つの階層に限定されず、影響を受けるすべてのエンティティまで遡る必要があります。

一般的なリレーショナル クエリは、グラフ データベースに適しています。しかし、当時は利用可能なグラフ データベースがなかったため、この問題は Oracle で解決する必要がありました。私より年下の同僚はこの機能を実現するために Java コードを書いていましたが、C/S 時代を経験していないのでしょう。プログラムの実行後、アプリケーション サーバーは継続的にこのテーブルにアクセスし、各レコードの関連付け関係を処理します。パフォーマンスは想像できますが、データ量が少ないテスト環境では、プログラムは 30 分間実行されました。これはユーザーの許容範囲をはるかに超えているため、最適化する必要があります。

同じロジックを実現するためにストアド プロシージャに切り替えました。これは、ネットワーク送信が必要なく、パフォーマンスが大幅に向上したためです。最終的に、ストアド プロシージャが同じ結果を得るまでに約 20 秒かかりました。よくやった!

4 ストアド プロシージャの問題

後に、このプログラムは移植性が低いことが判明しました。開発された製品は、関連する基本ソフトウェアの制約に従って、顧客環境に展開されます。

かつて、たまたまクライアントが Oracle を使用していなかったので、他の同僚が私が書いたロジックをクライアントが使用するデータベースに翻訳しました。TDB に移植できるストアド プロシージャは、結果が得られずに終了できません。このコードを追跡した結果、問題はロジック自体ではなくデータベースにあることが最終的にわかりました。このロジックでは再帰アルゴリズムを使用しました。これは、Oracle が深い再帰レベルをサポートしているため、実行に問題はありませんが、TDB は限られた再帰レベルのみをサポートしており、当時は多くのデータ関連付けがあったため、プログラムはエラーを報告し、短期間で終了しました。

この経験により、ストアド プロシージャに対する私の自信は少し揺らぎました。ストアドプロシージャは環境への依存度が高く、その環境は統一標準に準拠したオープンな環境ではなく、オペレーティングシステムやJava仮想マシンなどの技術情報が多く、あまり標準化されていないブラックボックスとなっているデータベースとして。

ただし、ストアド プロシージャの問題はそれだけではありません。C/S アーキテクチャで開発していたとき、ストアド プロシージャのデバッグが難しいという問題に遭遇しましたが、当時は誰もがこれは支払わなければならない代償だと考えていました。しかし、B/S アーキテクチャの出現と Java コード開発およびテスト技術の継続的な開発により、ストアド プロシージャのデバッグが難しいという問題がより顕著になってきました。現在、アジャイル開発はますます人気が高まっており、DevOps ツール チェーンは急速に発展していますが、ストアド プロシージャは依然として「独立」しています。

ここまで述べましたが、理解していただきたいのは、今日のストアド プロシージャとその年のトリガーは本質的に同じ問題に直面しているということです。テクノロジは当時のエンジニアリングレベルに適合し、テクノロジ エコロジー全体と統合されなければなりません。そうでないと、テクノロジは消滅してしまいます。ほとんどのアプリケーションシナリオに対応します

ほら、「Alibaba Java 開発マニュアル」にも「ストアド プロシージャの使用は禁止されています。ストアド プロシージャはデバッグや拡張が難しく、移植性がありません。」と印象的に書かれていますが、おそらく同様のことがあるのだと思います。私にとってのメンタル。

5 分散データベースのサポート

ほとんどの NewSQL 分散データベースはまだストアド プロシージャをサポートしていません。例外は OceanBase で、バージョン 2.2 で Oracle ストアド プロシージャのサポートが追加されました。これは Oracle 戦略との全体的な互換性の賜物だと思います。ただし、OceanBase の公式声明は、ストアド プロシージャの機能が現時点では運用要件を満たしていないことを明確にしています。

レガシー システムとの互換性は、今日のストアド プロシージャの最大の重要性である可能性があります。MySQL から分散データベースに移行するシステムの場合、これらのシステムはストアド プロシージャにあまり依存していないため、この魅力はそれほど強くない可能性があります。MySQL は新しいバージョンでのみストアド プロシージャを提供し、その機能は Oracle ほど強力ではないため、ユーザーへの依存度ははるかに小さくなります。ストアド プロシージャは NewSQL では広くサポートされていませんが、これはアーキテクチャ上の問題も原因です。

業界が何を試みているかをご覧ください。

Google は 2018 年に新しい F1 論文「 F1 Query: Declarative Querying at Scale 」を VLDB でリリースしました独立した UDF サーバーを通じてカスタム関数、つまりストアド プロシージャをサポートすることが提案されています。このアーキテクチャでは、F1 がデータ ストレージから完全に独立しているため、UDF サーバーが自然に抽出されます。論文に記載されているテストデータから判断すると、この設計は高いパフォーマンスを維持していますが、これは Google の強力なネットワーク設備によるところが大きいと思われ、一般的な企業ネットワーク環境で適用できるかどうかは微妙です。

UDFサーバーの設計

  • UDF は一般言語のサポートを実現しており、SQL に加えて、C++、Java、Go などの言語実装もサポートしています。これにより、データベースの SQL 言語に依存せず、論理表現の汎用性が高まります。
  • UDF はストレージ層に結合されていません。これは、そのコンテキストがよりオープンになる可能性があることを意味します。

これは、ストアド プロシージャのデバッグが大幅に改善され、DevOps システムとのインターフェイスが可能になる可能性があることを意味します。

以前、VoltDB はストアド プロシージャも改革しました。VoltDB は、データベース分野の伝説的な Michael Stonebraker によって開発されたメモリベースの分散データベースです。VoltDB は、メインの操作モードとしてストアド プロシージャを使用し、Java 言語での記述をサポートします。開発者は、システムによって提供される親クラス (VoltProcedure) を継承して、独自のストアド プロシージャを開発できます。

import org.voltdb.*;
public class LeastPopulated extends VoltProcedure {
    
    
  //待执行的SQL语句
  public final SQLStmt getLeast = new SQLStmt(
      " SELECT TOP 1 county, abbreviation, population "
    + " FROM people, states WHERE people.state_num=?" 
    + " AND people.state_num=states.state_num" 
    + " ORDER BY population ASC;" );
  
  //执行入口
  public VoltTable[] run(int state_num) 
      throws VoltAbortException {
    
    
         //赋输入参数
         voltQueueSQL( getLeast, state_num ); 
         //SQL执行函数
         return voltExecuteSQL();
      }
}

最初に SQL を定義します (「state_num=?」は予約済みのパラメータ位置)。次に、エントリ関数 run() でパラメータを割り当てて実行します。

VoltDB は設計思想が異なり、CPU の使用効率を重視しています。彼らは従来のデータベースを分析し、意味のあるデータ操作に使用されるのは通常のデータベースの CPU 時間の 12% のみであると考えました。そのため、その設計の多くは CPU リソースを最大限に活用することを中心に展開されています。

ストアド プロシージャは基本的に事前定義されたトランザクションであり、手動による対話プロセスがないため、CPU の待機が回避されます。同時に、ストアド プロシージャの内容は予測可能なため、データをできるだけ早くメモリにロードできるため、ネットワークやディスク I/O によって発生する CPU の待機時間がさらに短縮されます。

VoltDB がシングルスレッド モデルでも優れたパフォーマンスを実現できるのは、ストアド プロシージャとメモリの使用によるものです。逆に、単一スレッド自体はトランザクション制御を簡素化し、従来のロック管理と CPU 待機のオーバーヘッドを回避し、VoltDB のパフォーマンスを向上させます。

他のデータベースと比較すると、ストアド プロシージャは VoltDB にとってまったく異なる意味を持ちます。

6 まとめ

  1. ストアド プロシージャの移植が不十分です。データベース環境に大きく依存しており、データベース環境はオペレーティング システムや仮想マシンのような統一された標準に従っていません。同じ理由で、ストアド プロシージャのデバッグも非常に複雑で、アジャイル開発のペースに追いついておらず、今日のエンジニアリング要件にも適合していません。ストアド プロシージャが使用されないか、使用頻度が低くなっているのは、まさにこれら 2 つのエンジニアリング上の理由によるものです。
  2. 分散データベースの観点から見ると、ほとんどの NewSQL はストアド プロシージャをまだサポートしていません。唯一の例外として、OceanBase はすでに Oracle ストアド プロシージャをサポートしていますが、まだ運用レベルには達していません。
  3. F1 の論文では、分散アーキテクチャにおけるストアド プロシージャの実装スキームである独立 UDF サーバーのアイデアが提案されていますが、それが通常の企業ネットワーク環境に適しているかどうかはまだわかりません。ただし、このソリューションでは、ストアド プロシージャの実装言語が SQL 言語に限定されず、さまざまな主流言語に拡張され、標準と互換性があり、オープン性が向上します。これにより、ストアド プロシージャ テクノロジと DevOps が統合される可能性が高まります。
  4. インメモリ分散データベースとして、VoltDB は主な操作定義方法としてストアド プロシージャを使用し、Java 言語開発をサポートします。VoltDB の基礎は、ストアド プロシージャの事前定義されたトランザクション メソッドであるとさえ言えます。ストアド プロシージャ、メモリ ストレージ、およびシングル スレッドが相互に連携することで、VoltDB のパフォーマンスが優れています。

プログラマーにとって、習得して効率的に実行されてきたテクノロジーを放棄するのは難しい決断に違いありません。しかし今日、大規模なソフトウェア システムでは、特定のテクノロジー自体よりもエンジニアリング要件の方がはるかに重要です。テクノロジーエコシステム全体と連携できないテクノロジーは、最終的には疎外される運命を避けることはできません。分散データベースであれ、マイクロサービスであれ、新しいテクノロジを学ぶ前に、それが周囲の生態系に適応できるかどうかに注意を払うことをお勧めします。トレンドに適合するテクノロジには改良される可能性がありますが、あまりにも優れているためです。ニッチ テクノロジーには大きな不確実性が含まれています。

参考

7 よくある質問

VoltDB の設計思想は非常に特殊で、シングルスレッド、大量のメモリの使用、Java 言語をサポートするプロシージャの格納に加えて、データ レプリケーションの設計も独創的であり、Paxos プロトコルではありません。 NewSQL や PGXC のマスター/スレーブ レプリケーションはどのように設計されているか想像できるでしょうか。レプリケーション メカニズムとストアド プロシージャの間には特定の関係があります。

1. ビジネス コードと技術コードを分離する必要がある ビジネス ロジックからビジネス コードへの変換がシンプルかつ純粋であることを保証する必要があります。これは、実装段階で特定のテクノロジーとの結合を減らすだけでなく、ビジネス コードのテスト容易性とビジネス コードの単純さと一貫性を確保するためでもあります。
2. 特定のテクノロジ (ストアド プロシージャなど) の特性により、優れたパフォーマンスが実現される場合があります。しかし、これにより実装フェーズの複雑さも増大し、複雑さはメンテナンスの困難を意味し、コストとリスクを意味します。ソフトウェアの動作価値は実現されますが、アーキテクチャの品質の健全性は損なわれます。したがって、厳しいパフォーマンス要件があるシナリオでは、特定のテクノロジーの一部の機能を使用することは理解できますが、常に警戒し、これが両刃の剣であることを認識する必要があります。自分の「奥深いスキル」に基づいて無謀な行動をしないでください。
3. C/Sの時代を経験していない。ただし、データ モデル駆動設計に関する関連書籍を読むと、ストアド プロシージャが当初どのように人気があったのかがわかります。しかし、ストアド プロシージャなどの一連の手法が過去のものとなった現在、データ モデル駆動設計は非常に「貧血」になり始めています。基本的に、エンティティ関係モデルとデータ項目だけが残りますが、これは情報伝達能力が弱く、複雑なビジネス ソフトウェアの設計を推進するのには適していません。
4. 通信用のデータ モデル ドライバーの独自の実装を配置します: https://github.com/Jxin-Cai/mdd/tree/master/data-model/mini-faas

VoltDB のシャード レプリケーションは、rocketMq のネームサーバーに似ています。すべてのレプリカに対して操作を並行して実行することにより、レプリカ間で合意に達するという複雑さが回避されます。

OceanBaseがOracleのストアド・プロシージャをサポートする以外に選択肢はないのは、Oracleの従来の顧客陣営(大企業や純粋に商業目的である金融部門)に「侵入」できるかどうかを決めるからだ。オラクルのERP製品ではビジネスロジックを実装するために多数のストアドプロシージャが使用されており、最も複雑なビジネスロジックのソースコードは数十ページに渡って印刷されますが、OceanBaseのツールではこのような複雑なストアドプロシージャを完璧に扱える(OBに移植する)ことはできないと思います。ただし、入札などの場合は、Oracle の多くの機能をサポートしていない場合は、参加する機会がまったくありません。

VoltDB は K-safety メカニズムを使用して、データ レプリケーションの問題を解決します。実際には、これは N+1 コピー メカニズムです。VoltDB がデータを書き込むとき、各コピーでステートメントを実行し、データが正しく保存されていることを確認します。各コピーに挿入されます。すべての N+1 コピーは同時にアクセスを提供できますが、同時に最大 N コピーの損失 (パーティション障害) が許容されます。N+1 コピーが利用できない場合、VoltDB は修復のためにサービスを停止します。

「Alibaba Java 開発マニュアル」では、デバッグや拡張が難しく移植性のないストアドプロシージャの使用を禁止しています。「誤解を招く疑いがあります。ここでのストアド プロシージャは MySQL を対象としており、デバッグが非常に難しく、複製も困難です。同時代の製品では、ストアド プロシージャは Oracle の PL/SQL と SQL サーバーの T-SQL で書かれていました」 DB2 と Oracle はどちらも PL/SQL をサポートしており、PL/SQL は移植可能であり、このストアド プロシージャは SQL 標準 (SQL/PSM (SQL/Persistent Stored Modules) https://en.wikipedia.org) で呼び出されます。 org/wiki/SQL/PSM)。

Ali 開発マニュアルのこの提案は、特に MySQL について言及しているわけではありませんが、MySQL は Ali で広く使用されており、代表的なデータベースであるため、MySQL の章に含まれる可能性があります。ひそかに Oracle ストアド プロシージャを喜んで使用しながら、MySQL ストアド プロシージャを無効にしている可能性はありますか? ありそうにありません。

SQL 標準の開発と Oracle の開発を通じて、ストアド プロシージャのサポートにも開発プロセスがあり、ストアド プロシージャのパフォーマンスと開発効率は依然として非常に高いです。ビッグデータの時代、ストレージの分離が叫ばれ、ストレージはストレージに属し、計算は計算に属し、ハードウェアとコストのバランスに基づいて、水平拡張によって計算能力が向上し、ストレージの処理機能が強化されます。一時的に開発されていない、または開発が困難ですが、Apache ハイブはサポートされているストアド プロシージャは hpsql と呼ばれます。

さらに、SQL 標準はすべてのデータベースの参照にすぎず、データベースが異なれば、データ型、グローバル変数、関数、さらにはストアド プロシージャ名の長さも異なります。特別に調整しない限り、同一のデータベースはありません。系切り替えデータベースが大事と言われる所以です。

分散データベースの代表的なものは TiDB と CockroachDB です。これらは構文の互換性とストアド プロシージャのサポートが若干異なります。CockroachDB は pg 構文のストアド プロシージャをサポートしていますか (pg は PL/SQL に似ています)。

これらの違いを理解した後でも、これはそれほど簡単な問題ではないと感じる学生もいるかもしれません。個人にとって難しいか簡単かは非常に主観的な判断ですが、チームが低コストで長く使えるかどうかが鍵となります。

すべてのストアド プロシージャは JAVA をサポートしているため、データ レプリケーションは TCC から学習できるはずです。TCC はコード層 (「サービス層」に相当) に直接実装されており、メモリに基づいており、再試行のコストは次のとおりです。低、コードを直接使用してノードに書き込みます。

これらはすべてメモリに基づいていますが、Redis とは異なり、それほど高いパフォーマンスは必要なく、スレッド プールを直接使用して同時にデータ ノードにデータを書き込みます。

ストアド プロシージャはスタンドアロン データベース時代のかけがえのない製品であり、私がプログラマーだった頃、ストアド プロシージャはフロントエンド コードとバックエンド コードの分離を解決するための最良のツールでした。ストアド プロシージャを呼び出すことで 100,000 件の注文を一括レビューする操作は数分で完了しますが、フロントエンドの VB コードが実行され、結果が得られるのに 1 時間もかかりませんか?

はい、ストアド プロシージャは間違いなく、データ集約型コンピューティングにとって強力なツールです。

クリックハウスの実体化ビューは実はトリガーなのですが、どのような角度から分析すればよいのでしょうか?

機械的な観点から見ると、ClickHouse のマテリアライズド ビュー (MaterializedView) は確かにトリガーと見なすことができます。

  1. 機能角

マテリアライズド ビューの機能は、基本テーブルを事前計算し、SELECT クエリの結果をリアルタイムで維持することです。これは、リアルタイムで更新されるキャッシュ ビューを作成することと機能的には同等です。これは、データが変更されたときにトリガーが事前に設定されたアクションを自動的に実行する方法に似ています。

  1. 実装メカニズムの観点

ClickHouse はエンジンを通じてマテリアライズド ビューを作成し、基になるテーブルにデータが変更されると、マテリアライズド ビューの更新を自動的にトリガーします。これは、エンジンのトリガー メカニズムを利用して、リアルタイムのマテリアライズド ビューを実現します。

  1. シーンアングルを使用する

マテリアライズド ビューは、データ分析、ダッシュボード、および集計結果への素早いアクセスを必要とするその他のシナリオで使用でき、トリガーの使用と同様の繰り返しのクエリを置き換えます。

  1. パフォーマンスの観点

マテリアライズド ビューはキャッシュによって読み取りパフォーマンスを向上させますが、書き込み負荷が増加します。読み取りと書き込みの比率を比較検討して、使用するかどうかを決定する必要があります。これは、トリガーのパフォーマンスのトレードオフ特性も反映しています。

  1. 限界角度

マテリアライズド ビューにはクエリに関するさまざまな制限があり、これらの制限はトリガーが通常考慮する必要がある要素でもあります。

複数の観点からまとめると、ClickHouse のマテリアライズド ビューは確かに特別なトリガーとみなすことができ、マテリアライズド ビューを理解して使用するのに役立ちます。これにより、データベース内のさまざまな自動化メカニズムを分析するための新しい角度が得られました。

おすすめ

転載: blog.csdn.net/qq_33589510/article/details/132229106