質問に答える前に、ある程度の背景が整っていると思います。
問題の核心
長年にわたって開発者にインタビューして採用した後、2つのことを学びました。
開発者の大半は、データベース設計の経験がほとんどありません。
データベースを理解していない人と、ORMを嫌う人との間には、ゆるやかな相関関係があることに気付きました。
(注:はい、そうです、データベースを非常によく理解し、ORMを嫌う人がいることは知っています)
外部キーが重要である理由、item
テーブルにメーカー名を埋め込んでいない理由customer.address1
、または、、、customer.address2
およびcustomer.address3
フィールドがデータベースのバグを書きやすくするためにORMを追加するのは良い考えではない理由を人々が理解していないとき何の助けにもなりません。
代わりに、適切に設計されたデータベースとOLTPユースケースを使用すると、ORMは黄金になります。面倒な作業のほとんどはなくなり、DBIx :: Class :: Schema :: Loaderなどのツールを使用すると、優れたデータベーススキーマからPerlコードを数分で動作するようになります。私はパレート規則を引用し、私の問題の80%が作業の20%で解決されたと言いますが、実際には、それ以上のメリットがあると思います。
ソリューションの乱用
一部の人々がORMを嫌うもう1つの理由は、抽象化が漏れるからです。MVC Webアプリの一般的なケースを考えてみましょう。ここによく見られるものがあります(擬似コード):
GET '/countries/offices/$company' => sub {
my ( $app, $company_slug ) = @_;
my $company = $app->model('Company')->find({ slug => $company_slug })
or $app->redirect('/');
my $countries = $app->model('Countries')->search(
{
'company.company_id' => $company->company_id,
},
{
join => [ offices => 'company' ],
order_by => 'me.name',
},
);
$app->stash({
company => $company,
countries => $country,
});
}
人々はそのようなコントローラールートを書いて、自分自身を後ろで軽くたたいて、それは良い、きれいなコードだと思っています。彼らはコントローラーでSQLをハードコーディングすることにat然としますが、異なるSQL構文を公開する以上のことはしていません。ORMコードをモデルにプッシュダウンする必要があり、それを実行できます。
GET '/countries/offices/$company' => sub {
my ( $app, $company_slug ) = @_;
my $result = $app->model('Company')->countries($company_slug)
or $app->redirect('/');
$app->stash({ result => $result });
}
今何が起こっているか知っていますか?モデルを適切にカプセル化し、ORMを公開していません。後で、データベースの代わりにキャッシュからそのデータをフェッチできることがわかった場合、コントローラーコードを変更する必要はありません(そして簡単です)テストを作成し、ロジックを再利用します)。
実際には、コントローラー(およびビュー)全体でORMコードがリークされ、スケーラビリティの問題が発生すると、アーキテクチャではなくORMのせいになります。ORMは悪いラップを取得します(多くのクライアントでこれを繰り返し見ます)。代わりに、抽象化を非表示にして、ORMの制限に本当に達したときに、コードをORMに緊密に結合して独り占めするのではなく、問題に適したソリューションを選択できるようにします。
レポートおよびその他の制限
Rob Kinyonが上記で明らかにしたように、報告はORMの弱点になる傾向があります。これは、複雑なSQLまたは複数のテーブルにまたがるSQLがORMでうまく機能しない場合がある、より大きな問題のサブセットです。たとえば、ORMが私が望まない結合タイプを強制することがあり、それを修正する方法がわからないことがあります。または、MySQLでインデックスヒントを使用したいのですが、簡単ではありません。または、SQLが非常に複雑であるため、提供されている抽象化よりもSQLを記述する方が良い場合もあります。
これは、私がDBIx :: Class :: Reportを書き始めた理由の一部です。これまでのところ、それはうまく機能し、人々がここで抱えている問題の大部分を解決します(読み取り専用インターフェースで問題がなければ)。松葉杖のように見えますが、実際には、抽象化を漏らさない限り(前のセクションで説明したとおり)、作業がDBIx::Class
さらに簡単になります。
それで、いつDBIx :: Classを選択するのでしょうか?
私にとっては、ほとんどの場合、データベースへのインターフェイスが必要な場合に選択します。私は何年も使用しています。ただし、OLAPシステムには選択しないかもしれませんし、新しいプログラマーは確かにそれと格闘しています。また、メタプログラミングが必要であることがよくありDBIx::Class
ますが、ツールは提供されていますが、ドキュメント化が非常に不十分です。
DBIx::Class
正しく使用するための鍵は、ほとんどのORMと同じです。
抽象化を漏らさないでください。
ひどいテストを書いてください。
必要に応じて、SQLにドロップダウンする方法を知ってください。
データベースを正規化する方法を学びます。
DBIx::Class
、一度学習すれば、ほとんどの面倒な作業はあなたに代わって処理され、アプリケーションをすばやく作成するのが簡単になります。