Есть ли способ кеширования механизма для Class :: DBI? - PullRequest
3 голосов
/ 16 апреля 2009

У меня есть набор довольно сложных модулей ORM, которые наследуются от Class :: DBI . Поскольку данные изменяются довольно редко, я рассматриваю возможность использования слоя Caching / Memoization для ускорения процесса. Я нашел модуль: Class :: DBI :: Cacheable , но нет рейтинга или каких-либо отзывов о RT. Я был бы признателен людям, которые использовали эту или любую другую схему кэширования Class :: DBI.

Спасибо за тонну.

Ответы [ 3 ]

3 голосов
/ 05 октября 2009

Я тоже катал свой собственный 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
}

Вместо хеша вы можете использовать набор модулей Cache :: на CPAN для реализации ограничений времени и памяти в вашем кэше.

Если вы собираетесь кешировать какое-то время, возможно, вы захотите подумать о способе истечения срока действия объектов в кеше. Например, если все ваши обновления также проходят через ORM, вы можете очистить (или обновить) запись кэша в вашем методе ORM для update ().

Последний момент, о котором нужно тщательно подумать - вы возвращаете один и тот же объект каждый раз, что имеет значение. Если, например, один фрагмент кода извлекает объект и обновляет значение, но не фиксирует это изменение в БД, весь другой код, извлекающий этот объект, увидит это изменение. Это может быть очень полезно, если вы объединяете ряд операций - все они могут обновить объект, а затем вы можете зафиксировать его в конце - но это может быть не тем, что вы намеревались. Я обычно устанавливаю флаг на объекте, когда он только что из базы данных, а затем в вашем методе setter аннулируем этот флаг, если объект обновляется - таким образом, вы всегда можете проверить этот флаг, если вы действительно хотите свежий объект.

2 голосов
/ 01 октября 2009

В некоторых случаях мы катали свои собственные, но мы ограничивали его специальными случаями, когда профилирование указывало на необходимость повышения (например, большие объединения). Поскольку наши приложения обычно используют пользовательский уровень абстракции (похожий на доморощенный ORM) поверх доступа к БД, именно здесь мы реализовали кэширование. Мы добились хороших результатов, которые нас устраивали, и это не потребовало много усилий. Конечно, поскольку мы не использовали CPAN ORM, у нас на самом деле не было и выбора в использовании модуля кэширования CPAN.

Это был строго индивидуальный случай и согласие. Независимо от того, используете ли вы решение CPAN или переходите на собственное, лучше всего ограничить его случаями, когда профилирование означает, что вам нужна помощь, и убедитесь, что оно включено, чтобы кеширование не подорвало ваше приложение тонкими способами быть активным, когда вы этого не ожидали.

0 голосов
/ 16 апреля 2009

Я использовал memcached , прежде чем кешировать объекты , но не с Class :: DBI (ORM заставляет меня чувствовать себя грязным).

...