Antes de responder a la pregunta, creo que algunos antecedentes están en orden.
El núcleo del problema
Después de años de entrevistar y contratar desarrolladores, aprendí dos cosas:
La gran mayoría de los desarrolladores tienen muy poca experiencia en el diseño de bases de datos.
He notado una correlación floja entre los que no entienden las bases de datos y los que odian los ORM.
(Nota: y sí, sé que hay quienes entienden muy bien las bases de datos que odian los ORM)
Cuando la gente no entiende por qué claves externas son importantes, ¿por qué no incrusta el nombre del fabricante en la item
mesa, o por qué customer.address1
, customer.address2
y customer.address3
los campos no son una buena idea, la adición de un ORM para que sea más fácil para ellos errores de base de datos de escritura No va a ayudar nada.
En cambio, con una base de datos diseñada adecuadamente y un caso de uso OLTP, los ORM son dorados. La mayor parte del trabajo duro desaparece y con herramientas como DBIx :: Class :: Schema :: Loader , puedo pasar de un buen esquema de base de datos a un código Perl en cuestión de minutos. Citaría la Regla de Pareto y diría que el 80% de mis problemas se han resuelto con el 20% del trabajo, pero en realidad, encuentro los beneficios aún mayores que eso.
Abusando de la solución
Otra razón por la que algunas personas odian los ORM es porque dejarán escapar la abstracción. Consideremos el caso común de las aplicaciones web MVC. Aquí hay algo que comúnmente vemos (pseudocódigo):
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,
});
}
La gente escribe rutas de control así y se da palmaditas en la espalda, pensando que es un código bueno y limpio. Estarían horrorizados al codificar el SQL en sus controladores, pero han hecho poco más que exponer una sintaxis SQL diferente. Su código ORM debe insertarse en un modelo y luego pueden hacer esto:
GET '/countries/offices/$company' => sub {
my ( $app, $company_slug ) = @_;
my $result = $app->model('Company')->countries($company_slug)
or $app->redirect('/');
$app->stash({ result => $result });
}
¿Sabes lo que pasó ahora? Ha encapsulado correctamente su modelo, no ha expuesto el ORM, y más tarde, cuando descubra que puede obtener esos datos de un caché en lugar de la base de datos, no necesita cambiar el código de su controlador (y es más fácil escribir pruebas para ello y reutilizar la lógica).
En realidad, lo que sucede es que las personas filtran su código ORM en todos sus controladores (y vistas) y cuando se topan con problemas de escalabilidad, comienzan a culpar al ORM en lugar de a su arquitectura. El ORM tiene una mala reputación (lo veo repetidamente para muchos clientes). En su lugar, oculte esa abstracción para que cuando haya alcanzado realmente los límites de ORM, pueda elegir las soluciones apropiadas para su problema en lugar de permitir que el código esté tan estrechamente unido al ORM que esté atado.
Informes y otras limitaciones
Como Rob Kinyon dejó en claro anteriormente, los informes tienden a ser una debilidad en los ORM. Este es un subconjunto de un problema mayor en el que SQL complicado o SQL que abarca varias tablas a veces no funciona bien con ORM. Por ejemplo, a veces el ORM fuerza un tipo de unión que no quiero y no puedo decir cómo solucionarlo. O tal vez quiero usar una pista de índice en MySQL, pero no es fácil . O, a veces, el SQL es tan complicado que sería mejor escribir el SQL en lugar de la abstracción proporcionada.
Esta es parte de la razón por la que comencé a escribir DBIx :: Class :: Report . Hasta ahora funciona bien y resuelve la mayoría de los problemas que las personas tienen aquí (siempre y cuando estén bien con una interfaz de solo lectura). Y aunque parezca una muleta, en realidad, siempre y cuando no esté filtrando su abstracción (como se explicó en la sección anterior), hace que trabajar con él sea DBIx::Class
aún más fácil.
Entonces, ¿cuándo elegiría DBIx :: Class?
Para mí, lo elegiría la mayoría de las veces que necesito una interfaz para una base de datos. Lo he estado usando por años. Sin embargo, es posible que no lo elija para un sistema OLAP, y los programadores más nuevos ciertamente tendrán dificultades con él. Además, a menudo encuentro que necesito meta-programación y, aunque DBIx::Class
proporciona las herramientas, están muy poco documentadas.
La clave para usar DBIx::Class
correctamente es la misma que para la mayoría de los ORM:
No pierdas la abstracción.
Escribe tus malditas pruebas.
Sepa cómo desplegarse a SQL, según sea necesario.
Aprenda a normalizar una base de datos.
DBIx::Class
, una vez que lo aprenda, se encargará de la mayor parte de su trabajo pesado y hará que sea muy fácil escribir aplicaciones rápidamente.