もうStored Proceduresはやめよう、アプリ開発者からの懇願
We need to stop using Stored Procedures
アプリケーションからStored Proceduresを呼び出すのをやめるべきだと著者は主張する。パラメータ化クエリとプランキャッシュの利点は通常のクエリでも得られ、むしろアプリとDBアクセスロジックを同じバージョンで管理できる。ネットワークリクエスト、インデックス、ORM、デカルト積爆発など、アプリ開発者が知るべきDB操作の基本も解説する。
アプリケーション開発者よ、頼むから、Stored Proceduresへの依存をコードベースに入れるのはやめてくれ。
HNでの議論
30- saxenaabhi
これは非常に稚拙に書かれていて、基本的な事実で間違っている。
> では、ストアドプロシージャは何をもたらすのか?
> 何もない!いや、頭痛の種はあるな。
> ... クエリを更新するためにマイグレーションをデプロイしなければならないし、diff migration_for_my_sproc migration_for_my_sproc_n を実行して何が変わったか確認しなければならない
1) SQL関数はコードと一緒にリポジトリでバージョン管理し、DBマイグレーションと一緒に(同じトランザクションでさえ)デプロイできる。
SQL関数ごとに1ファイルにしておけば、私のように600個のストアドプロシージャがあるリポジトリでも、チェックサムを計算して高速化できる。
2) ストアドプロシージャを使えば、複数のステートメントを実行するときにサーバーで db.startTransaction を呼び出してDBのラウンドトリップを待つ必要がない。これがストアドプロシージャを好む最大の理由であることが多い。
3) 医療や金融のシステムで、異なるチームが基盤となるテーブルにアクセスできず、DBはSQLプロシージャだけを公開しているのを見たことがある。プロシージャが呼び出されるたびに、監査テーブルにログエントリが追加される。
データベースは素晴らしい技術だ!正しく使う方法を学べば、ビジネス価値の創出という点で大きな見返りが得られる。
編集:この記事では触れられていないが、ストアドプロシージャのテストの難しさがよく言及される。
通常のvitestテストで、インメモリのpgliteを使ってPostgres関数をテストできる。
- JeffRosenberg
> アプリケーションコードとDBアクセスは別々にバージョン管理され、我々のsprocは異常な(つまり極めて稀で非常識な)DBAによって足元から変えられうる
あなたのデータベース(とそのマイグレーション)は、他のコードと一緒にソース管理されるべきだ。問題解決。これでストアドプロシージャが提供する正当な利点のいくつかを活用できる!
- est
ストアドプロシージャは、データストレージのすぐ近くで動作する、強く型付けされた「サーバーレスラムダ」のようなものだと思う。
- hbarka
これは明らかにアプリケーション開発者のバイアスから来ている意見だ。データエンジニアならストアドプロシージャのアイデアが好きだ。データエンジニアは、特に一括変換、セットベース処理、ETL/ELT、データ品質ルール、大量データを扱う場合に、ロジックをデータの近くに置く方が快適なことが多い。それを処理するためだけにアプリケーションで行うのは非効率的だ。
- bunderbunder
かつてはストアドプロシージャ推進派だったが、クエリをデータベーススキーマの一部にすることは負担が大きく、避けたい開発上の摩擦を生むことに同意する。
私は主にクエリをアプリケーションのリポジトリに *.sql ファイルとして保存する方に移行した。それでも優れたクエリキャッシュと予測可能なプランは得られる。さらに、クエリとそれを使うコードが一緒にバージョン管理されることや、開発者がSQLコンソールでクエリを簡単にテストできることなど、他の嬉しい特典もある。ほとんどのエディタには、開発用データベースへの接続文字列と引き換えにオートコンプリートと基本的なエラーチェックを提供するプラグインさえある。
後者の点が、文字列リテラル内のインラインSQLやORMのクエリDSLが好きでない理由だ。どちらもクエリをいじって動作を観察することを妨げる。これが、開発者がクライアント側で集計を計算するようなひどいパフォーマンス上の罪を犯すのがよくある大きな理由だと思う。プロジェクトのデータベース相互作用が、そうすることを積極的に妨げるように設定されているのに、人々がSQLウィンドウ関数に慣れることを期待するのは難しい。