有没有办法为Class :: DBI缓存机制?

时间:2009-04-16 17:06:21

标签: perl caching memoization class-dbi

我有一组从Class::DBI继承的相当复杂的ORM模块。由于数据变化很少,我正在考虑在此基础上使用缓存/记忆层来加快速度。我找到了一个模块:Class::DBI::Cacheable但没有评级或对RT的任何评论。我希望听到使用过这个或任何其他Class :: DBI缓存方案的人的意见。

非常感谢。

3 个答案:

答案 0 :(得分:3)

我也厌恶说出我自己的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 :: suite模块来实现缓存中的时间和内存限制,而不是散列。

如果您要缓存一段时间,可能需要考虑一种使缓存中的对象失效的方法。例如,如果所有更新都通过ORM,则可以在update()ORM方法中清除(或更新)缓存条目。

要仔细思考的最后一点 - 每次都会返回相同的对象,这会产生影响。例如,如果一段代码检索一个对象并更新一个值但没有将该更改提交给db,那么检索该对象的所有其他代码都将看到该更改。如果你将一系列操作串联起来,这可能非常有用 - 它们都可以更新对象,然后你可以在最后提交它 - 但它可能不是你想要的。我通常在数据库中新鲜时在对象上设置一个标志,然后在setter方法中如果对象更新则使该标志无效 - 这样,如果你真的想要一个新对象,你总是可以检查该标志。

答案 1 :(得分:2)

有几次我们已经推出了自己的产品,但我们将其限制在特殊情况下,其中分析表明我们需要提升(例如大型连接)。由于我们的应用程序通常在数据库访问之上使用自定义抽象层(类似于自行开发的ORM),因此我们实现了缓存。我们取得了令人满意的良好成果,并没有花费太多精力。当然,由于我们没有使用CPAN ORM,我们也没有选择使用CPAN缓存模块。

严格按个别情况选择加入。无论您最终使用的是CPAN解决方案还是自己编写解决方案,最好将其限制在分析表明您需要帮助的情况下,并确保选择加入,以便您的缓存不会以微妙的方式破坏您的应用程序当你没想到它时,你会被激活。

答案 2 :(得分:0)

我之前使用memcachedcache objects,但没有使用Class :: DBI(ORM让我觉得很脏)。