0

現在、PostgreSQLデータベースがあり、いくつかのPerlバインディングを介してデータベースにアクセスし、データベースにアクセスして、Perlタイプへの応答をマーシャリングします。これは問題なく動作しますが、さまざまな理由でPerlに不満を持っています。私たちが検討してきたオプションの1つは、このAPIの作業の大部分をplpgsqlストアドプロシージャとしてデータベース自体に移動することです。

簡単な例

たとえば、データベースに次のものがあるとします。

-- This matches our 'Entity::Artist' object
CREATE TYPE loaded_artist (
  artist_id uuid,
  revision_id integer,
  artist_tree_id integer,
  name text,
  sort_name text,
  artist_type_id integer,
  -- etc
);

-- This gets the latest 'master' version of an artist and joins in basic data
-- from the artist tree
CREATE FUNCTION get_latest_artist_by_mbid(in_mbid UUID)
RETURNS SETOF loaded_artist AS $$
  BEGIN
    RETURN QUERY
    SELECT
      artist_id, revision_id, artist_tree_id, name.name,
      sort_name.name AS sort_name, artist_type_id
    FROM artist
    JOIN artist_revision USING (artist_id)
    JOIN artist_tree USING (artist_tree_id)
    JOIN artist_data USING (artist_data_id)
    WHERE artist.master_revision_id = revision_id
      AND artist_id = in_mbid;
  END;
$$ LANGUAGE 'plpgsql';

これで、現在のPerl APIを簡略化して、効果的に次のようにすることができます。

package Data::Artist;
sub get_latest_by_mbid {
    my ($self, $mbid) = @_;
    return $self->new_from_row(
        $self->sql->select_single_row_hash(
            'SELECT * FROM get_latest_artist_by_mbid(?)',
            $mbid));
}

これは賢明ですか?

額面では、私はこれが好きです。我々:

  • Perlから離れますが、別の言語にコミットしないでください。これは、将来的に実際のアプリケーションをPythonなどに移行でき、APIの大部分がすでに完了していることを意味します。
  • 次のようなものを指定することにより、PostgreSQLから追加の型安全性を取得しますRETURNS SETOF loaded_artist
  • PGTAPを介した単体テストなどはまだあります。

いくつかの欠点があります。

  • データベース内の関数を置き換える必要があるため、開発サイクルが短縮される可能性があります。世界の終わりではありませんが、これにより、以前は存在しなかった「コンパイル」ステップがワークフローに効果的に導入されます。
  • 潜在的に難しいバージョン管理ですが、確かにそれを行う方法があります

誰かがこのような仕事をしましたか?あなたはそれを奨励しますか、それとも危険に満ちていましたか?


脚注:私たちのケースについてもう少し

これはオープンソースのウェブサイト用です。データベースのダンプを配布して、PostgreSQLデータベースにインポートできるようにします。PGからすぐに移行する予定はないため、データベースにとらわれない決定は実際には当てはまりません。私たちは非常に小さなチーム(2人の有料開発者、より多くのオープンソース貢献者)であり、これにより、展開戦略に関して非常に柔軟になります。

4

2 に答える 2

4

利点:

  • データベーススキーマ/レイアウト/ストレージの変更は、アプリケーションから完全に隠されています。
  • データベースを操作するための統合APIがあります。
  • すべてのSELECTクエリを含め、データベースで実行されたすべてのアクションについて広範なログを記録できます。

短所:

  • 優れたDBAの必要性の高まり。
  • データベースがデータをどのように処理し、DB側の手順がどのように機能するかを十分に理解しているデータベース開発者のニーズの高まり。
  • DB側とアプリケーション側のチーム間でより多くの調整が必要になります。
  • ORM統合の難しさ。
  • ストアドプロシージャを使用すると、データベースの最適化の可能性が制限され、一部のクエリ(特にレポート)でパフォーマンスの問題が発生します。オプティマイザは述語をビューにプッシュダウンしてインデックスを適切に利用できるため、代わりにビューを使用することをお勧めします。

最適な組み合わせは、ラッパー関数だけでなく、データベース側でビジネスロジックの取引を実装する場合です。

スキーマバージョン管理が可能です。構成テーブルのデータをバージョン管理するのはより注意が必要です。私が関わっているプロジェクトの1つでは、これはこの部分を処理する外部ツール(perlベース)を介して行われます。

  • データは最初に中間テーブルにロード/抽出されます。
  • 次に、RIの制約と考えられるすべての違反について分析されます。
  • ライブテーブルにロードする前にデータ操作が可能です。
  • 複数のテーブルを生成するビジネスオブジェクトは、一度に定義および抽出できます。
  • 一致するエンティティを処理する方法はいくつかあります。たとえば、上書き、マージ、複製などです。

代わりに抽出ファイル(プレーンSQL)をバージョン管理しており、インストールスクリプトに新しい構成をロードするための特別な手順があります。

于 2012-07-05T10:28:27.673 に答える
0

移植性の点まで:

  • すでに述べたように、ストアドプロシージャを使用することで、クライアントでの移植性が向上します。
  • ストアドプロシージャを使用しないことで、サーバー上での移植性が向上します(別のDBMSに簡単に移動できます)。
于 2012-07-05T10:53:16.020 に答える