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

发布于 2024-07-17 08:51:06 字数 350 浏览 10 评论 0原文

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

万分感谢。

I have a set of rather complex ORM modules that inherit from Class::DBI. Since the data changes quite infrequently, I am considering using a Caching/Memoization layer on top of this to speed things up. I found a module: Class::DBI::Cacheable but no rating or any reviews on RT. I would appreciate hearing from people who have used this or any other Class::DBI caching scheme.

Thanks a ton.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柠檬色的秋千 2024-07-24 08:51:06

我也曾多次推出过自己的 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 方法中清除(或更新)缓存条目。

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

I too have rolled my own ORM plenty of times I hate to say! Caching/Memoization is pretty easy if all your fetches happen through a single api (or subclasses thereof).

For any fetch based on a unique key you can just cache based on a concatenation of the keys. A naive approach might be:

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
}

Instead of a hash, you can use the Cache:: suite of modules on CPAN to implement time and memory limits in your cache.

If you're going to cache for some time you might want to think about a way to expire objects in the cache. If for instance all your updates also go through the ORM you can clear (or update) the cache entry in your update() ORM method.

A final point to think carefully about - you're returning the same object each time which has implications. If, eg., one piece of code retrieves an object and updates a value but doesn't commit that change to the db, all other code retrieving that object will see that change. This can be very useful if you're stringing together a series of operations - they can all update the object and then you can commit it at the end - but it may not be what you intend. I usually set a flag on the object when it is fresh from the database and then in your setter method invalidate that flag if the object is updated - that way you can always check that flag if you really want a fresh object.

流星番茄 2024-07-24 08:51:06

在某些情况下,我们推出了自己的产品,但我们将其仅限于分析表明我们需要增强的特殊情况(例如大型连接)。 由于我们的应用程序通常在数据库访问之上使用自定义抽象层(类似于自行开发的 ORM),因此我们在其中实现缓存。 我们取得了令我们满意的好成绩,而且没有花费太多的努力。 当然,由于我们没有使用 CPAN ORM,因此我们对于使用 CPAN 缓存模块也没有任何选择。

这是严格根据具体情况和选择加入的。 无论您最终使用 CPAN 解决方案还是推出自己的解决方案,最好将其限制在分析表明您需要帮助的情况下,并确保它是选择加入的,这样您的缓存就不会以微妙的方式破坏您的应用程序在你没有预料到的时候变得活跃起来。

On a few occasions we've rolled our own, but we limited it to special cases where profiling indicated we needed a boost (for example large joins). Since our applications typically use a custom abstraction layer (akin to a home-grown ORM) on top of the DB access, that's where we implemented the caching. We achieved good results that we were satisfied with and it didn't take a whole lot of effort. Of course, since we weren't using a CPAN ORM, we didn't really have any choice about using a CPAN caching module, either.

It was strictly case-by-case and opt-in. Whether you end up using a CPAN solution or rolling your own, it's probably a good idea to restrict it to cases where profiling indicates you need help, and make sure that it's opt-in so your caching doesn't undermine your application in subtle ways by being active when you didn't expect it.

[旋木] 2024-07-24 08:51:06

我之前使用过 memcached 缓存对象,但不使用 Class::DBI (ORM 让我感觉很脏)。

I have used memcached before to cache objects, but not with Class::DBI (ORM makes me feel dirty).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文