Class::DBIから継承するかなり複雑な ORM モジュールのセットがあります。データはめったに変更されないため、この上にキャッシング/メモ化レイヤーを使用して処理を高速化することを検討しています。モジュールClass::DBI::Cacheableを見つけましたが、RT に関する評価やレビューはありません。これまたは他の Class::DBI キャッシング スキームを使用したことがある人からの連絡をお待ちしています。
ありがとうございます。
Class::DBIから継承するかなり複雑な ORM モジュールのセットがあります。データはめったに変更されないため、この上にキャッシング/メモ化レイヤーを使用して処理を高速化することを検討しています。モジュールClass::DBI::Cacheableを見つけましたが、RT に関する評価やレビューはありません。これまたは他の Class::DBI キャッシング スキームを使用したことがある人からの連絡をお待ちしています。
ありがとうございます。
私も自分のORMを何度もロールバックしました。すべてのフェッチが単一のAPI(またはそのサブクラス)を介して行われる場合、キャッシュ/メモ化は非常に簡単です。
一意のキーに基づくフェッチの場合、キーの連結に基づいてキャッシュすることができます。素朴なアプローチは次のようになります。
my %_cache;
sub get_object_from_db {
my ($self, $table, %table_lookup_key) = @_;
# concatenate a unique key for this object
my $cache_key = join('|', map { "$_|$table_lookup_key{$_}" }
sort keys %table_lookup_key
return $_cache{$cache_key}
if exists $_cache{$cache_key};
# otherwise get the object from the db and cache it in the hash
# before returning
}
ハッシュの代わりに、CPANのCache ::モジュールスイートを使用して、キャッシュに時間とメモリの制限を実装できます。
しばらくの間キャッシュする場合は、キャッシュ内のオブジェクトを期限切れにする方法を検討することをお勧めします。たとえば、すべての更新がORMを通過する場合は、update()ORMメソッドのキャッシュエントリをクリア(または更新)できます。
慎重に考える最後のポイント-毎回同じオブジェクトを返すことになりますが、これには影響があります。たとえば、1つのコードがオブジェクトを取得して値を更新したが、その変更をデータベースにコミットしなかった場合、そのオブジェクトを取得する他のすべてのコードはその変更を認識します。これは、一連の操作をつなぎ合わせる場合に非常に役立ちます。これらの操作はすべてオブジェクトを更新し、最後にコミットできますが、意図したものではない場合があります。私は通常、オブジェクトがデータベースから新しいときにフラグを設定し、setterメソッドで、オブジェクトが更新された場合にそのフラグを無効にします。これにより、本当に新しいオブジェクトが必要な場合は、いつでもそのフラグを確認できます。
いくつかのケースで独自のロールを作成しましたが、プロファイリングでブーストが必要であることが示された特別なケース (大規模な結合など) に限定しました。私たちのアプリケーションは通常、DB アクセスの上にカスタムの抽象化レイヤー (自家製の ORM に似ています) を使用するため、そこにキャッシングを実装しました。私たちは満足できる良い結果を達成しました。もちろん、CPAN ORM を使用していなかったので、CPAN キャッシング モジュールを使用する選択肢もありませんでした。
それは厳密にケースバイケースであり、オプトインでした。最終的に CPAN ソリューションを使用する場合でも、独自のソリューションを導入する場合でも、プロファイリングで支援が必要であることが示された場合に限定して、オプトインであることを確認して、キャッシングがアプリケーションを微妙な方法で弱体化させないようにすることをお勧めします。予期しないときにアクティブになることによって。