DBICでテーブル名切替の術

アプリを作ってると色々ログ系をDBに保存しておきたかったりするのですが、
ログテーブルって結構でかくなってしまう運命です。
DBによってはテーブルサイズがでかくなると検索効率が落ちてしまったり
ちょくちょく問題になってしまうのですが、
ログテーブルを年月ごととかで分割すると結構さくさく扱えたりします。

ただ、普通にDBIC使ってると分割したログテーブル毎にスキーマを用意する必要が
でてきてしまうです。

例えば
access_logってテーブルがあるとして、これを年月で分割して保存させるばやい、

access_log        : Proj::Schema::AccessLog
access_log_200706 : Proj::Schema::AccessLog200706
access_log_200707 : Proj::Schema::AccessLog200707
access_log_200708 : Proj::Schema::AccessLog200708

このようにテーブルに対応するスキーマを作る必要があります。

しかし
access_logとaccess_log_*は同じテーブル構造にしておくと、
Proj::Schema::AccessLogを一個つくれば他のaccess_log_*のテーブル用で
スキーマを作らなくてもよい方法があります。

普通にProj::Schema::AccessLogだけを作っておいて検索する時に

$self->model->source_registrations->{AccessLog}->name('access_log_200706');
my @logs = $self->model('AccessLog')->search->all;

こうするだけ。
source_registrations->{AccessLog}->nameがテーブル名に対応しているので、
そのテーブル名の部分を検索したいテーブル名に差し替えるだけで
差し替えたテーブル名を使って検索できます。
もちろんこれでInsertやUpdateなどもいけます。

ただ、これだとaccess_log_200706とaccess_log_200707をあわせて検索とかできないですが、
その場合はMERGEをつかってやればいいかと思います。

例えば、MERGEを使ってaccess_log_mergeというテーブルを作ってやって
source_registrations->{AccessLog}->name
access_log_mergeを指定するとおk

実際にこういう形で運用してみて良い感じでやっておるます。
MERGEはやってませんが。

ちなみにうちの場合
access_logをベースのテーブルにしておいて
access_logと同じ構造のテーブルを必要になった時点で

CREATE TABLE IF NOT EXISTS $table_name LIKE access_log

と動的に生成してます
MySQL依存なSQLですけど。
こういう感じで動的テーブル生成することで、Cronでログを別テーブルに移したりとかしなくて良い感じです。