plpgsql 以外の手続き型言語 (PL/Python、PL/Perl、PL/v8 など) を使用して、モデル レベルではなくデータベース レベルでデータ操作ロジックを実装することの利点と欠点を理解しようとしています。データベースとやり取りするアプリケーション フレームワーク (Rails、Entity Framework、Django など) の ORM とそこへの実装。
具体的な例を挙げると、Mustacheテンプレートを含むテーブルがあり、何らかの方法でそれらを「レンダリング」したいとします。テーブル定義:
create table templates (
id serial primary key,
content text not null,
data jsonb not null
);
通常、モデル コードに移動し、テンプレートをレンダリングするメソッドを追加します。Rails での例:
class Template < ApplicationRecord
def rendered
Mustache.render(content, data)
end
end
ただし、データベース レベルでそれを実行する PL/Python 関数を作成することもできます。
create or replace function fn_mustache(template text, data jsonb)
returns text
language plpython3u
as $$
import chevron
import json
return chevron.render(template, json.loads(data))
$$;
create view v_templates as
select id, content, data, fn_mustache(content, data) as rendered
from templates;
これにより、機能的には実質的に同じ結果が得られます。この例は非常に基本的なものですが、アイデアは PL/Python (またはその他) を使用して、PL/pgsql が可能にするよりも高度な方法でデータを操作することです。つまり、PL/pgsql には、現在提供されている汎用プログラミング言語と同じ量のライブラリがありません (この例では、Mustache テンプレート システムの実装に依存していますが、この場合、PL/pgsql で実装するのは実用的ではありません)。もちろん、ネットワークやその他の OS レベルの機能に PL/Python を使用するつもりはありませんが、データのみを操作する場合、これは適切なアプローチのように思えます (考えを変えてください)。
これまでに観察できるポイント:
- PL/Python は「信頼できない」言語であり、syscall にアクセスできるため、定義上、関数を記述するのがより危険になると思います。少なくとも、PL/Python 関数を台無しにするコストは、アプリケーション層での間違いよりも高いように感じます。なぜなら、前者はデータベースのコンテキストで実行されるからです。
- データベース アプローチは、データに最も近いレベルで作業しているため、より拡張性があります。つまり、プレゼンテーション ロジックを複数の「層」(この場合は ORM と DB) に分散させていません。これは、データとの対話に関心のある他の外部サービスが必要な場合、アプリケーション層をバイパスしてデータベースに直接プラグインできることを意味します。
- これをモデルレベルで実装すると、実行がはるかに簡単に見えます
- 覚えておくべき概念が少ないため、アプリケーション コード バリアントのサポートも簡単に思えます。
これら 2 つのアプローチのその他の長所と短所は何ですか? (例: パフォーマンス、保守性)