ストアドプロシージャ vs ビジュアルワークフロー:ロジックをどこに置くべきか
Stored procedures とビジュアルワークフロー:どのロジックをデータベース、ドラッグ&ドロップのワークフロー、またはカスタムコードに置くべきかを実践的に判断する方法。

この判断が本当に意味すること
ビジネスロジックは、何が許されるか、次に何が起きるか、実際の人が操作したときにシステムがどう振る舞うかを決める一連のルールです。データ自体ではなく、振る舞いです:誰が何をできるか、どんな条件で、どんな副作用があるか。
つまり「ストアドプロシージャ vs ビジュアルワークフロー」の議論は、これらのルールをどこに置けば変更しやすく、壊れにくく、プロセスの責任者にとって明確でいられるか、という話です。
ほとんどのチームはロジックの“居場所”を三つのうちのどれかに収めます:
- データベース内(ストアドプロシージャ、トリガー、制約): ルールがデータに近い場所で動きます。高速で一貫性が出せますが、データベース専門家以外には変更が難しいことがあります。
- ビジュアルワークフロー(ドラッグ&ドロップのプロセスビルダー): ルールがステップと判断として表現されます。読みやすく、レビューや調整がしやすい場合が多いです。
- カスタムコード(サービス、アプリ、スクリプト): ロジックをプログラミング言語で書きます。最も柔軟ですが、変更にはより厳格なエンジニアリングとテストが必要になります。
選択は日々の速度と長期的な保守性に影響します。間違った場所にロジックを置くと、配信が遅くなり(変更にはデータベースの詳しい人が必要)、エラーが増え(複数箇所でルールが複製される)、デバッグが辛くなります(なぜレコードが拒否されたか誰もわからない)。
多くのシステムにはいくつかの種類のビジネスロジックが混在します。一般例としてはバリデーション(必須フィールド、許容範囲)、承認、価格や割引、通知、アクセスルールなどがあります。
実用的に考えると、データベースはデータ整合性の保護に優れ、ビジュアルワークフローはビジネスプロセスの表現に優れ、カスタムコードはルールがモデル化しにくく複雑な場合に強い、ということです。AppMasterのようなプラットフォームはその中間に位置しており、データをモデル化して可読なビジュアルロジックでプロセスを実装でき、ルールが多くのアプリに散らばることを防げます。
最適化したいもの:何を守るのか
これは好みの問題ではなく、何を守ろうとしているかの問題です:データ、システムを変更する人々、変更の速度。
重要な成果指標
プロジェクトの最重要成果を明確にしてください。ほとんどのチームは次のいくつかを天秤にかけています:
- 正確性: 負荷下でもルールは常に同じように動かなければならない。
- 明瞭性: 新しい人が推測なしに何が起きるか理解できること。
- 速度: 必要ならデータに近いところで高速に動くこと。
- 監査性: 誰が何を変更し、いつそれが実行されたかを証明できること。
- 変更頻度: 要件が週次で変わるのか年次でしか変わらないのか。
五つすべてを最大化することは稀です。ロジックをデータベース寄りにすると正確性と速度は上がるが、SQLに馴染みのない人にとっての明瞭性は下がります。
誰がどれくらいの頻度でロジックを変更するか
日々の変更を誰が担うか正直に見極めてください。運用が週単位で微調整する必要があるルールをDBAに頼まないと変更できない場所に置くべきではありません。一方で、金銭に関わるルールはレビューなしで編集できてはいけません。
変更摩擦で考えてください。要件が頻繁に変わるなら、更新が安全で可視化されていて素早く出せる場所が必要です。ビジネスオーナーとエンジニアが低レベルコードを編集せずに協働できるビジュアルワークフローツール(たとえば AppMaster の Business Process Editor)はこの場合に有効です。逆に変更が稀でルールが重要なら、摩擦が大きくても許容できます。
所有権をテストする簡単な方法:
- 午前2時に壊れたら誰に電話が行くか?
- ルールをどれくらい急いでパッチする必要があるか?
- 変更に承認や記録が必要か?
- 複数のアプリが同じルールに依存するか?
- ロジックは主にデータの整形か、ビジネス判断か?
業界によっては厳しいアクセス制御、職務分離、詳細なログが要求されます。特定のサービスだけが特定フィールドを見られるべき、というデータアクセス制限も考慮してください。
ロジックをストアドプロシージャに置くべきとき
ストアドプロシージャはデータベース内部で動くロジックです。PostgreSQLではSQLやPL/pgSQLなどで書かれます。アプリが行を取り出してループして戻す代わりに、データベース側で直接処理を行います。
簡単なルール:主な役割がデータ保護や大量データ処理であればデータベースに置きます。人やシステムの調整が主な役割なら別の場所を選びます。
ストアドプロシージャが得意な場面
すべてのアプリや統合が触れても常に真でなければならないルールには向いています。悪いデータを防ぐガードレールです。
また、集合単位の更新(1つの命令で何千行も安全かつ高速に更新)にも適しています。合計を計算したり固定の割引式を適用したりといった、純粋にデータに関する単純な計算は往々にしてここに置くと往復を減らせて一貫性が保てます。
例:注文が paid とマークされたとき、手続きをアトミックに実行して注文ステータスを更新し、在庫を減らし、監査行を記録する。どれかが失敗したら全体がロールバックされる。
ストアドプロシージャがリスクになるとき
ストアドプロシージャはアプリケーションコードに比べてテストやバージョン管理が難しくなりがちです。チームがデータベース変更を正式なリリースと扱わないと、ロジックがアプリから“隠れる”ことになり、後で強い結合に気づくことがあります。
デバッグもつらくなります。エラーはデータベースのメッセージとして出て、ユーザーが何をしたかという文脈が不足することがあります。新人はアプリとデータベースにロジックが分散していると苦労します。
ビジュアルツールでほとんどのロジックを扱っているなら、ストアドプロシージャはデータに近く動く小さく安定したコアに限定し、その他は読みやすく追跡しやすい場所に置いてください。
ロジックがビジュアルワークフローに向くとき
ビジュアルワークフローは、チェックリストのように読めるステップごとのプロセスロジックです:何かが起きたら順にこのアクションを実行し、明確な判断点があります。重い計算というよりは、仕事が人やシステム、時間をまたいでどう流れるかに向いています。
共有理解が重要な場合に力を発揮します。プロダクト、運用、サポート、エンジニアがプロセスの仕組みについて合意する必要があるなら、ビジュアルワークフローはルールを可視化します。可視性があるかどうかは、「システムが壊れた」か「先週プロセスが変わった」かの差になることが多いです。
承認・レビュー、ルーティング、通知・リマインダー、時間を伴うステップ(2日待ってエスカレーション)、外部連携(Stripe 呼び出し、メッセージ送信、CRM 更新)などが得意分野です。
例:顧客が返金を要求する。ワークフローは注文の経過日数を確認し、閾値を超えていればマネージャーに回し、承認されたら会計に通知し、顧客に更新を送る。各ステップは平易な言葉で指し示せるので、利害関係者の合意を得やすく、新しいメンバーも「なぜこうするか」を理解しやすくなります。
AppMaster の Business Process Editor のようなツールは、パス、条件、メッセージやAPI呼び出し、ステータス変更などの副作用をスクリプトを掘らずに可視化できます。
ワークフローをスパゲッティにしないために、小さく読みやすく保ってください。各ワークフローは一つの結果に集中させ、ステップや分岐にわかりやすい名前を付け、深いネストを避け、主要な選択をログに残して後で「なぜこれが起きた?」に答えられるようにします。
ワークフローが複雑なデータ処理や多くのテーブルに触れ始めたら、その一部を他に移すサインです。ビジュアルワークフローは指揮者として機能するのがベストで、全てを担うべきではありません。
カスタムコードが適切なとき
カスタムコードはアプリの一部として書いて保守する関数やサービス、ライブラリです。最も柔軟なので、目的を持って使うべきです。
データベースやドラッグ&ドロップで安全に表現しにくいロジックにはコードが向いています。道具を無理に合わせていると感じたら、コードにしたほうが明快で保守しやすいことが多いです。
コードを選ぶ強いサイン:
- 問題がアルゴリズム的(価格ルール、ルート計画、スコアリング、マッチング、詐欺検出)で多数のエッジケースがある。
- 特殊な統合が必要(奇妙な認証、複雑な再試行、厳しい冪等性)でパートナーAPIを扱う場合。
- パフォーマンスが敏感(高ボリューム処理、重い計算、厳密なキャッシュ制御)で厳密な制御が必要な場合。
- 同じロジックを複数箇所(ウェブ、モバイル、バッチ)で共有し、コピペを避けたい場合。
- ミスのコストが高く、自動化されたテストが必須な場合。
コードは所有権を明確にします。チームがレビューし、テストを維持し、振る舞いを文書化する責任を持てます。これは「3つのワークフローに散らばっていてどれが先に動くか誰も分からない」より優れた状態です。
例:注文履歴、詐欺シグナル、配送状況、時間窓を考慮する返金の判定エンジン。承認のステップはビジュアルワークフローに残しつつ、判定自体はユニットテストとバージョン管理がしやすいコードにするのがよいことが多いです。
コストは現実的です。カスタムコードはエンジニアリング時間、レビュー、継続的な保守が必要で、変更はワークフロー編集より時間がかかります。AppMaster は共通部分をビジュアルロジックやモジュールでカバーしつつ、必要な箇所だけソースをエクスポートして拡張できるようにして、この負担を減らします。
再利用できるステップバイステップのフレームワーク
多くのチームは最も有用な部分を飛ばします:ルールを明確に書いてから、その振る舞いに合う居場所を選ぶことです。
新しいロジックが現れたら、このフレームワークを使ってください:
- ルールを一文で書いてラベルを付ける。 それが有効データに関するもの(制約、ユニーク、合計が一致する等)ならデータルール。ステップや引き渡し(承認、待ち、通知)ならプロセスルール。重い数学や複雑変換なら計算ルール。
- 誰がどのくらいの頻度で編集するか問う。 非技術者が週単位で変える必要があるならSQLやコードリリースに埋めないでください。稀で常に強制されるべきならデータベースが有力候補です。
- 失敗の影響と必要な監査トレイルを確認する。 誤りが金銭損失やコンプライアンス問題を引き起こすなら、記録と厳密な管理が得られる場所を選んでください。
- 場所を選び境界を定義する。 入力、出力、エラーを明示します。例:「
order_idを与えられたらallowed_refund_amountを返すか明確な理由コードを返す」。その境界がロジックの漏れを防ぎます。 - 一つのレイヤーを薄く保つ。 どこを“賢くしない”か決めてルールの複製を避けます。一般的な選択肢は:データベースは薄く(データ整合性のみ)、ワークフローは薄く(オーケストレーションのみ)、コードは薄く(接着のみ)にする、など。
経験則:データルールはデータに近く、プロセスルールはワークフローに、計算ルールはテストやバージョン管理がしやすい場所に置いてください。
AppMaster を使うなら、データベースはガードレール(テーブル、関係、基本制約)として扱い、ビジュアル Business Process Editor は「誰が次に何をするか」を表現し、カスタムコードは本当に必要な部分に限定します。
混乱したシステムを作る一般的な間違い
混乱したシステムは一つの悪い選択が原因で起きることは稀です。ロジックが散らばり、隠れ、複製されて誰もシステムが何をするか分からなくなることで発生します。
複製は典型的な問題です:同じルールが二箇所にあり、時間とともに乖離する。例:データベースは $500 を超える返金を承認レコードがないと拒否しているのに、ワークフローは別の制限で支払い処理に進めてしまう。どちらも一見動くが、端のケースでサポートに謎のバグが降ってきます。
次は隠れたルールです。トリガーやストアドプロシージャ、データベース内の即席修正はUIやワークフローを作る人に見えにくくなります。ワークフローやAPI近くに記録されていないルールは、変更が推測ベースになりテストが試行錯誤になります。
詰め込み過ぎたワークフローは別の種類の混乱を生みます。多数の分岐を持つ長いドラッグ&ドロップチェーンは誰も触りたくない壊れやすいアーティファクトになります。AppMaster のようなツールではブロック追加が簡単なため速度に任せて積み上げがちですが、その速度が後で混乱を招くことがあります。
「多すぎ」の両極端が長期的な痛みを生みます:
- データベースに入れすぎる: ポリシー変更ごとにマイグレーションが必要になり、小さな製品調整がデータベースのリリース待ちになる。
- アプリコードに入れすぎる: 基本的なデータルール(必須フィールド、許容ステータス、ユニーク制約)が忘れられ、インポートや管理ツール、将来の統合から不正データが入り込む。
簡単な習慣で大半は防げます:各ルールを一つの主要な居場所に保ち、どこにあるかと理由を書き残す。もし「どこで強制されているか」を10秒で答えられなければ、もう混乱の税金を払っています。
2分で決めるクイックチェック
ルールをどこに置けば最も正しく、見えやすく、変更しやすいかを選びます。
まず一つ質問:このルールはデータの正確性に関するものか(常にバイパスされてはならない)? もしそうならデータベース寄りに置いてください。ステップや承認、通知に関するものならワークフロー層に近い方がよいです。
迅速チェックリスト:
- データ正確性を強制しているか(在庫の負数防止、重複する「active」レコードのブロックなど)? データベース寄り。
- 多数のテーブルに触れ集合的更新が必要か? データベース寄り。
- 誰が何をいつ承認したかの可読な監査証跡が必要か? ワークフロー寄り。
- 非エンジニアが週次・月次で変更する必要があるか? ワークフロー寄り。
- 外部サービス(支払い、メッセージ、AI)を呼ぶか? アプリケーションかワークフロー寄りで、データベースではない。
失敗についても考えてください。失敗は人が回復できる形で起きるべきです。
安全な再試行と明確なエラーメッセージが必要なら、状態を追跡し例外処理ができるオーケストレーション層を選んでください。ビジュアルワークフローツールは各ステップが明示されログを取りやすいためこれを簡単にします。
実用的な決め手:
- 将来誰かが新しいアプリを書いてもシステムの正しさを保ちたいなら、データベースで強制する。
- 運用チームが読んでレビューすることが目的なら、ビジュアルワークフローに置く。
- 複雑な統合や重い計算、特殊ライブラリが必要ならカスタムコードを使う。
例:「Refund amount cannot exceed original payment」は正確さの問題なのでデータ近くで強制。「Refunds over $500 require manager approval and then send a Telegram message」はワークフローです。AppMaster では承認チェーンは Business Process Editor に自然に収まり、厳格な制約はデータモデルに残します。
例:承認付き返金シナリオ
よくあるケースは、一定額を超える返金にマネージャー承認が必要で、通知と明確な監査トレイルも求められる場合です。
まず単一の真実のソースを定義します:金額と明確なステータスフィールド(例:requested, needs_approval, approved, rejected, processing, paid, failed)を持つ Refund レコードを一つにします。システムのどの部分も同じフィールドを読み書きし、並列の状態を複数に持たないようにします。
データベースにふさわしいもの
お金とデータの一貫性を守るルールはデータに最も近い場所に置きます。
制約(と場合によってはストアドプロシージャ)を使って、捕捉された支払額を超える返金ができないこと、既に全額返金済みの注文には返金できないこと、同じ注文に対して二つのアクティブな返金要求を作れないこと、承認後に主要金額を変更できないこと、などを保証します。
また原子更新もここに置きます:返金要求を作成するとき、Refund 行を書き込みつつ Order の合計を同一トランザクションで更新します。どちらかの書き込みが失敗したら何も部分的に更新されてはいけません。
ビジュアルワークフローに向くもの
承認ステップはプロセスであり、データ保護ではありません。リクエストを適切なマネージャーに回す、意思決定を待つ、ステータスを更新する、リマインダーを送る、申請者に通知を送る、などがワークフローの居場所です。
単純な流れの例:request を作成 -> 金額が閾値を超えていればステータスを needs_approval にする -> マネージャーに通知 -> 承認されたら approved にする -> 申請者に通知 -> 24時間応答がなければリマインドを送る。
AppMaster のようなツールでは、これが Business Process としてステータス変更に反応し、メール、SMS、Telegram をトリガーする形で綺麗にマッピングできます。
カスタムコードに置くべきもの
支払いプロバイダーにはルールに収まりにくいエッジケースがあります。部分返金と手数料、マルチキャプチャ支払い、ウェブフックの突合(プロバイダーは「paid」だがアプリは「processing」と言う)、タイムアウト時の冪等性と再試行処理などはカスタムコードに置くべきです。
重要なのは、カスタムコードが独自のステータスを作らないことです。カスタムコードは Refund レコードを読み、プロバイダーアクションを実行し、次のステータスと確定金額を書き戻して、データベースがみんなの信頼できる元帳であり続けるようにします。
次のステップ:決定を定着させる
良い決定も6ヶ月後に守られなければ意味がありません。目標は「どこにロジックを置くか」の選択が見やすく、テストしやすく、偶発的に回避されにくいことです。
シンプルなロジックマップを作ってください:主要なルールとそれぞれの居場所の短いリストを作り、ルールが変わったら更新します。ルール名、どこにあるか(データベース、ワークフロー、カスタムコード)、理由(1文)、読み書きするもの、誰が変更を承認するかを含めます。
境界を「交渉不可」として書き残しておくと、後で機能を追加するときにシステムを守れます。例:「データベースは X を保証する」「ワークフローは Y を強制する」。例えばデータベースは refund レコードが order なしで存在できないことを保証し、ワークフローは $500 を超える返金がマネージャー承認を必要とすることを強制する、という具合です。
変更前にテスト計画を立ててください。大きなテスト計画は不要で、ルールが変わるたびに再実行するいくつかのケースがあれば十分です:
- ハッピーパス(期待される入力、期待される結果)
- 失敗パス(データ不足、無効なステータス、重複リクエスト)
- 同時実行(同じアクションを同時に複数人がトリガーする)
- セキュリティ(ユーザーがステップをスキップしたり直接エンドポイントを叩こうとする)
所有権とレビュー規則も決めてください。誰がストアドプロシージャを編集できるか、ワークフローを編集できるか、何がピアレビューを必要とするかを決めることが、システムが健全であり続けるか放置状態になるかの分かれ目です。
ノーコードでドラッグ&ドロップのワークフローを使いつつもバックエンド構造を失いたくないなら、AppMaster のようなプラットフォーム(appmaster.io)は実用的な折衷案です:データをモデル化し、Business Process Editor でプロセスを表現し、要件が変われば再生成してデプロイできます。
1つの高インパクトなルールを選び、マップを作り、境界を書き、3つのテストケースを書いてください。その習慣だけでロジックスプロールの多くを防げます。
よくある質問
データの整合性ルールはデータベースの近くに、手順に関するプロセスはワークフローに、複雑でテストが必要なルールはコードに置く、つまり正しく、見える化され、変更しやすい場所に置いてください。
ストアドプロシージャは、データ保護や大量データ処理に向いています。すべてのアプリや統合から常に守るべき不変条件、集合的な更新、一貫性が必要な原子トランザクションに使い、可能な限り小さく安定したものにして“隠れたロジック”にならないようにします。
ビジュアルワークフローはプロセスルール(承認、ルーティング、通知、待ちステップ、統合の順序)に最適です。非エンジニアや横断的チームがプロセスを確認・調整する必要がある場合に特に有効です。
以下のようなアルゴリズム的または特殊なロジックにはカスタムコードを選びます:複雑な価格計算、詐欺判定、マッチング/スコアリング、再試行や冪等性に厳しい統合、特殊なライブラリが必要な処理。ミスのコストが大きいなら自動テストが書けるコードが適しています。
お金に関わるルールは、不可欠な整合性はデータベースに、承認や通知などのプロセスはワークフローに置いて分離します。混ぜると、小さなプロダクト変更がデータベースのリリース待ちになったり、UI を迂回して不正なデータが入るリスクが出ます。
各ルールは一つの主要な居場所に置き、他の層はそれを呼び出すようにします。重複実装は、UIでは動いてもデータベースで失敗する、という問題を招きます。
ワークフローを小さく保つこと:明確な1つの結果、単純な分岐、読みやすいステップ名。ワークフローが大量のデータ処理や多くのテーブルに触れ始めたら、計算部分をコードに切り出すか整合性はデータベースに移してください。
データベースロジックもソフトウェア変更として扱えば解決します:バージョン管理、コードレビュー、テスト、どこで強制されているかのドキュメント化。さらに、エラーはワークフローやAPIレイヤーで説明できる形にしておきます。
アクセス制御や整合性制約はデータ層で強制し、誰がいつ何を承認したかというプロセストレイルはワークフローレイヤーで明示的に残します。こうすると監査が容易になります。
AppMasterは構造化されたデータと読みやすいプロセスロジックの中間に位置する実用的な選択肢です。PostgreSQLベースのデータをモデル化し、Business Process Editorで業務プロセスを表現し、コアのガードレールはストアドプロシージャ、エッジケースはコードで処理できます(appmaster.io)。


