Bevor ich die Frage beantworte, denke ich, dass einige Hintergründe angebracht sind.
Der Kern des Problems
Nachdem ich jahrelang Entwickler interviewt und eingestellt habe, habe ich zwei Dinge gelernt:
Die überwiegende Mehrheit der Entwickler verfügt über sehr wenig Erfahrung im Datenbankdesign.
Ich habe eine lockere Korrelation zwischen denen, die Datenbanken nicht verstehen, und denen, die ORMs hassen, festgestellt.
(Anmerkung: und ja, ich weiß, dass es diejenigen gibt, die Datenbanken sehr gut verstehen und ORMs hassen.)
Wenn die Leute nicht verstehen , warum Fremdschlüssel sind wichtig, warum Sie nicht die Herstellernamen in der einbetten item
Tabelle, oder warum customer.address1
, customer.address2
und customer.address3
Felder sind keine gute Idee, eine ORM Hinzufügen , um es für sie leichter zu schreiben Datenbank Bugs wird nichts helfen.
Stattdessen sind ORMs mit einer ordnungsgemäß gestalteten Datenbank und einem OLTP-Anwendungsfall Gold wert. Die meisten der Grunzenarbeit weggeht und mit Werkzeugen wie DBIx :: Class :: Schema :: Loader kann ich von einem guten Datenbankschema gehen zu Perl - Code in Minuten arbeiten. Ich würde die Pareto-Regel zitieren und sagen, dass 80% meiner Probleme mit 20% der Arbeit gelöst wurden, aber in Wirklichkeit finde ich die Vorteile noch größer.
Missbrauch der Lösung
Ein weiterer Grund, warum manche Leute ORMs hassen, ist, dass sie die Abstraktion auslaufen lassen. Betrachten wir den allgemeinen Fall von MVC-Webanwendungen. Folgendes sehen wir häufig (Pseudocode):
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,
});
}
Die Leute schreiben so Controller-Routen und klopfen sich auf den Rücken, weil sie denken, es sei guter, sauberer Code. Sie wären entsetzt darüber, SQL in ihren Controllern hart zu codieren, aber sie haben kaum mehr getan, als eine andere SQL-Syntax aufzudecken. Ihr ORM-Code muss in ein Modell übertragen werden, und dann können sie dies tun:
GET '/countries/offices/$company' => sub {
my ( $app, $company_slug ) = @_;
my $result = $app->model('Company')->countries($company_slug)
or $app->redirect('/');
$app->stash({ result => $result });
}
Weißt du was jetzt passiert ist? Sie haben Ihr Modell ordnungsgemäß gekapselt, den ORM nicht verfügbar gemacht und später, wenn Sie feststellen, dass Sie diese Daten aus einem Cache anstelle der Datenbank abrufen können, müssen Sie Ihren Controller-Code nicht ändern (und das ist einfacher Tests schreiben und die Logik wiederverwenden).
In Wirklichkeit verlieren die Benutzer ihren ORM-Code auf allen Controllern (und Ansichten), und wenn sie auf Skalierbarkeitsprobleme stoßen, geben sie eher dem ORM als ihrer Architektur die Schuld. Das ORM bekommt einen schlechten Ruf (das sehe ich bei vielen Kunden immer wieder). Verstecken Sie stattdessen diese Abstraktion, damit Sie, wenn Sie die ORM-Grenzen tatsächlich erreicht haben, geeignete Lösungen für Ihr Problem auswählen können, anstatt den Code so eng mit dem ORM zu verknüpfen, dass Sie sich nicht mehr auskennen.
Berichterstattung und andere Einschränkungen
Wie Rob Kinyon oben klargestellt hat, ist die Berichterstattung in der Regel eine Schwäche in Bezug auf ORMs. Dies ist eine Teilmenge eines größeren Problems, bei dem kompliziertes SQL oder SQL, das sich über mehrere Tabellen erstreckt, mit ORMs manchmal nicht gut funktioniert. Beispielsweise erzwingt der ORM manchmal einen Join-Typ, den ich nicht möchte, und ich kann nicht sagen, wie das behoben werden soll. Oder vielleicht möchte ich einen Index-Hinweis in MySQL verwenden, aber es ist nicht einfach . Oder manchmal ist die SQL einfach so verdammt kompliziert, dass es besser wäre, die SQL zu schreiben, als die bereitgestellte Abstraktion.
Dies ist einer der Gründe, warum ich angefangen habe, DBIx :: Class :: Report zu schreiben . Bisher funktioniert es gut und löst die meisten Probleme, die die Leute hier haben (sofern sie mit einer schreibgeschützten Oberfläche einverstanden sind). Und während es in der Realität wie eine Krücke aussieht , macht es die Arbeit mit DBIx::Class
noch einfacher , solange Sie Ihre Abstraktion nicht verlieren (wie im vorherigen Abschnitt erläutert) .
Wann würde ich DBIx :: Class wählen?
Für mich würde ich es meistens wählen, dass ich eine Schnittstelle zu einer Datenbank benötige. Ich benutze es seit Jahren. Ich würde es jedoch möglicherweise nicht für ein OLAP-System auswählen, und neuere Programmierer werden mit Sicherheit damit zu kämpfen haben. Außerdem stelle ich häufig fest, dass ich Metaprogramme benötige, und obwohl DBIx::Class
die Tools zur Verfügung gestellt werden, sind sie sehr schlecht dokumentiert.
Der Schlüssel zur DBIx::Class
korrekten Verwendung ist der gleiche wie bei den meisten ORMs:
Leck die Abstraktion nicht aus.
Schreiben Sie Ihre verdammten Tests.
Wissen, wie Sie bei Bedarf auf SQL zugreifen können.
Erfahren Sie, wie Sie eine Datenbank normalisieren.
DBIx::Class
Sobald Sie es gelernt haben, erledigen Sie die meisten Aufgaben für Sie und das schnelle Schreiben von Bewerbungen ist ein Kinderspiel.