web-dev-qa-db-fra.com

Vous utilisez un ORM ou un SQL simple?

Pour certaines des applications que j'ai développées (puis que j'ai oubliés), j'ai écrit du langage SQL simple, principalement pour MySQL. Bien que j'ai utilisé des ORM dans python comme SQLAlchemy , je ne les ai pas suivis longtemps. Habituellement, c'était soit la documentation, soit la complexité (de mon point de vue ) me retient.

Je le vois comme ceci: utilisez un ORM pour la portabilité, un SQL simple s'il ne s'agit que d'un type de base de données. Je cherche vraiment des conseils sur le moment d'utiliser ORM ou SQL lors du développement d'une application nécessitant un support de base de données.

À bien y penser, il serait bien préférable d'utiliser un wrapper léger pour gérer les incohérences de la base de données plutôt que d'utiliser un ORM.

233
hydrapheetz

Les ORM ont quelques fonctionnalités intéressantes. Ils peuvent gérer une grande partie du travail consistant à copier des colonnes de base de données dans des champs d'objet. Ils gèrent généralement la conversion des types de date et d'heure de la langue dans le type de base de données approprié. Ils gèrent généralement les relations un à plusieurs de manière assez élégante en instanciant des objets imbriqués. J'ai constaté que, si vous concevez votre base de données en gardant à l'esprit les forces et les faiblesses de l'ORM, vous économiserez beaucoup de travail pour obtenir des données dans la base de données. (Vous voudrez savoir comment il gère le polymorphisme et les relations plusieurs à plusieurs si vous avez besoin de les cartographier. Ce sont ces deux domaines qui fournissent la plupart des "incompatibilités d'impédance" qui font que certains appellent ORM le "vietnam de l'informatique" .)

Pour les applications transactionnelles, c’est-à-dire que vous effectuez une requête, récupérez des objets, parcourez-les pour récupérer des données et les restituez sur une page Web, la taxe sur les performances est faible et, dans de nombreux cas, ORM peut être plus rapide, car il mettra en cache les objets qu’il cache. vu auparavant, cela aurait autrement interrogé la base de données plusieurs fois.

Pour les applications qui génèrent beaucoup de rapports ou traitent un grand nombre de lignes de base de données par demande, la taxe ORM est beaucoup plus lourde, et la mise en cache qui en découle se transforme en un lourd fardeau de mémoire inutile. Dans ce cas, un mappage SQL simple (LinQ ou iBatis) ou des requêtes SQL codées à la main dans un DAL fin est la solution.

J'ai trouvé que pour toute application à grande échelle, vous utiliserez les deux approches. (ORM pour CRUD simple et SQL/DAL fin pour le reporting).

163
Cameron Pope

En tant que personne qui a passé pas mal de temps à travailler avec JPA (API de persistance Java, essentiellement l'API normalisée ORM pour Java/J2EE/EJB), qui inclut Hibernate, EclipseLink, Toplink, OpenJPA et d'autres, je partagerai certaines de mes observations.

  1. Les ORM ne sont pas rapides. Ils peuvent convenir et la plupart du temps, c'est correct, mais dans un environnement à volume élevé et à faible temps de latence, il s'agit d'un non-non;
  2. Dans les langages de programmation d'usage général tels que Java et C #, vous avez besoin de beaucoup de magie pour les faire fonctionner (par exemple, le tissage au moment du chargement en Java, l'instrumentation, etc.);
  3. Lorsque vous utilisez un ORM, plutôt que de vous éloigner de SQL (ce qui semble être l'intention), vous serez étonné du temps que vous passez à peaufiner XML et/ou les annotations/attributs pour que votre ORM génère un SQL performant;
  4. Pour les requêtes complexes, il n'y a vraiment pas de substitut. Comme dans JPA, il y a des requêtes impossibles à réaliser qui sont en SQL brut et lorsque vous devez utiliser du SQL brut dans JPA, ce n'est pas joli (C # /. Net a au moins des types dynamiques - var - ce qui est beaucoup plus agréable qu'un tableau d'objets);
  5. Il y a énormément de "pièges" lors de l'utilisation d'ORM. Cela inclut les comportements inattendus ou inattendus, le fait que vous deviez intégrer la possibilité d'effectuer des mises à jour SQL dans votre base de données (en utilisant refresh () dans JPA ou des méthodes similaires, car JPA met par défaut tout en cache afin de ne pas intercepter une base de données directe. update - l'exécution de mises à jour SQL directes est une activité courante d'assistance à la production);
  6. La discordance objet-relationnel va toujours causer des problèmes. Avec un tel problème, il existe un compromis entre la complexité et la complétude de l'abstraction. J’ai parfois eu le sentiment que JPA allait trop loin et appliquait une véritable loi des rendements décroissants, où la complexité n’était pas justifiée par l’abstraction.

Il y a un autre problème qui nécessite un peu plus d'explications.

Le modèle traditionnel pour une application Web consiste à avoir une couche de persistance et une couche de présentation (éventuellement avec un service ou d'autres couches entre les deux, mais ce sont les deux éléments les plus importants pour cette discussion). Les ORM forcent une vue rigide de votre couche de persistance jusqu'à la couche de présentation (c'est-à-dire vos entités).

L'une des critiques des méthodes SQL plus brutes est que vous vous retrouvez avec tous ces objets VO (objets de valeur) ou DTO (objets de transfert de données) utilisés par une seule requête. Ceci est présenté comme un avantage des ORM parce que vous vous en débarrassez.

Le problème est que ces problèmes ne disparaissent pas avec les ORM, ils se déplacent simplement jusqu'au niveau présentation. Au lieu de créer des VO/DTO pour les requêtes, vous créez des objets de présentation personnalisés, généralement un pour chaque vue. Comment est-ce meilleur? IMHO ce n'est pas.

J'ai écrit à ce sujet dans ORM ou SQL: sommes-nous encore là? .

Ma technologie de persistance de choix (en Java) ces jours-ci est ibatis. C’est un emballage assez fin autour de SQL qui réalise 90% + de ce que JPA peut faire (il peut même charger des relations paresseuses même s’il n’est pas bien documenté), mais avec beaucoup moins de surcharge (en termes de complexité et de code réel).

Cela est apparu l'année dernière dans une application GWT que j'écrivais. Beaucoup de traduction d'EclipseLink en objets de présentation dans l'implémentation du service. Si nous utilisions ibatis, il aurait été beaucoup plus simple de créer les objets appropriés avec ibatis, puis de les transmettre de haut en bas. Certains puristes pourraient dire que c'est Bad ™. Peut-être que oui (en théorie) mais je vous dis quoi: cela aurait conduit à un code plus simple, à une pile plus simple et à une plus grande productivité.

243
cletus

Je dis SQL simple pour [~ # ~] r [~ # ~] eads, ORM pour [~ # ~] cud [~ # ~] .

La performance est quelque chose qui me préoccupe toujours, en particulier dans les applications Web, mais également la maintenabilité et la lisibilité du code. Pour résoudre ces problèmes, j’écris SqlBuilder .

41
Max Toro

ORM n'est pas simplement une question de portabilité (ce qui est un peu difficile à atteindre même avec des ORM, d'ailleurs). Cela vous donne essentiellement une couche d'abstraction sur un magasin persistant, lorsqu'un outil ORM vous libère de l'écriture de requêtes SQL standard (sélections par PK ou par prédicats, insertions, mises à jour et suppressions) et vous permet de vous concentrer sur le domaine problématique.

14
Anton Gogolev

Toute conception respectable nécessitera une certaine abstraction de la base de données, uniquement pour gérer le désaccord des impédances. Mais la première étape la plus simple (et adéquate dans la plupart des cas) est sans doute un DAL, pas un ORM de poids lourd. Vos seules options ne sont pas celles du bout du spectre.


EDIT en réponse à un commentaire me demandant de décrire comment je distingue DAL de ORM:

Un DAL est ce que vous écrivez vous-même, peut-être à partir d'une classe qui encapsule simplement une table et mappe ses champs sur des propriétés. Un ORM est un code que vous n'écrivez pas ou des mécanismes d'abstraction déduits d'autres propriétés de votre schéma dbms, principalement des PK et des FK. (C’est là que vous découvrez si les abstractions automatiques commencent à couler ou non. Je préfère les informer intentionnellement, mais c’est peut-être ma préférence personnelle).

11
dkretz

Chaque outil a son but et sa vision. J'ai créé http://www.jooq.org/ exactement pour répondre à vos besoins, bien qu'iBatis soit probablement une bonne solution pour vous aussi.

jOOQ possède des fonctionnalités de base ORM, mais il se concentre principalement sur les éléments dont la plupart des développeurs ont le plus besoin, quand ils essaient de trouver le meilleur ORM pour leurs besoins:

  • génération de code
  • liaison variable (c'est une douleur dans JDBC)
  • Abstraction de la syntaxe SQL (pour éviter les erreurs de syntaxe)

Mais souvent, ils vont trop loin et fournissent tellement d'abstraction que vous ne penseriez pas qu'ils se heurtent à un SGBDR. D'autre part, vous avez choisi un SGBDR précisément parce que

  • c'est une source de données robuste
  • SQL peut faire beaucoup de choses bonnes et performantes (sélections imbriquées, unions, jointures complexes, etc.). Souvent, les ORM ne peuvent pas faire ces choses.
  • vous pouvez gérer vous-même les transactions et les sessions
  • vous avez des UDT et des procédures stockées

jOOQ aborde exactement ces points. Il fonctionnera aussi bien que JDBC, mais sans la douleur.

7
Lukas Eder

La clé qui a fait que mon utilisation ORM a vraiment volé était la génération de code. Je conviens que la route ORM n'est pas la plus rapide, en termes de performances de code. Mais lorsque vous avez une équipe de moyenne à grande taille, la base de données change rapidement. La possibilité de régénérer des classes et des mappages à partir de la base de données dans le cadre du processus de construction est une chose brillante à voir, en particulier lorsque vous utilisez CI. Donc, votre code n'est peut-être pas le plus rapide, mais votre code sera - je sais ce que je prendrais dans la plupart des projets.

Ma recommandation est de développer en utilisant un ORM pendant que le schéma est encore fluide, utilisez le profilage pour trouver les goulots d'étranglement, puis réglez les zones qui en ont besoin en utilisant des fichiers bruts.

Autre idée: la mise en cache intégrée à Hibernate peut souvent apporter des améliorations considérables en termes de performances si elle est utilisée correctement. Plus besoin de retourner dans la base de données pour lire les données de référence.

6
MrTelly

Le dilemme d'utiliser ou non un framework est assez courant dans les scénarios de développement de logiciels modernes.

Ce qui est important à comprendre, c’est que chaque cadre ou approche a ses avantages et ses inconvénients - nous avons par exemple constaté, dans notre expérience, que ORM était utile pour les transactions, c’est-à-dire les opérations d’insertion/mise à jour/suppression - mais pour la récupération de données complexes résultats, il devient important d’évaluer la performance et l’efficacité de l’outil ORM.

Il est également important de comprendre qu’il n’est pas obligatoire de choisir un cadre ou une approche et de tout mettre en œuvre. Nous entendons par là que nous pouvons combiner ORM et langage de requête natif. De nombreux frameworks ORM attribuent des points d’extension au plugin en SQL natif. Nous devrions essayer de ne pas trop utiliser un cadre ou une approche. Nous pouvons combiner certains cadres ou approches et proposer une solution appropriée.

Vous pouvez utiliser ORM pour l'insertion, la mise à jour, la suppression et la gestion de versions avec un niveau élevé de simultanéité. Vous pouvez également utiliser le SQL natif pour la génération de rapports et les listes longues.

5
Rutesh Makhijani

Il n'y a pas de solution unique, et cela vaut également pour la question "devrais-je utiliser un ou/m ou non? '.

Je dirais: si vous devez écrire une application/un outil qui est très "axé sur les données", sans autre logique, alors je me servirais de SQL pur, car SQL est le langage spécifique à ce domaine pour ce type d’applications.

Par ailleurs, si j’écrivais une application métier/entreprise contenant beaucoup de logique de "domaine", j’écrirais un modèle de classe riche pouvant exprimer ce domaine en code. Dans ce cas, un mappeur OR/M peut s'avérer très utile pour le faire, car il vous enlève beaucoup de code de plomberie.

4
Frederik Gheysels

Je sais que cette question est très ancienne, mais je pensais pouvoir poster une réponse au cas où quelqu'un la rencontrerait comme moi. Les ORM ont parcouru un long chemin. Certains d’entre eux vous offrent le meilleur des deux mondes: rendre le développement plus productif et maintenir les performances.

Jetez un coup d'œil à SQL Data ( http://sqldata.codeplex.com ). C'est un ORM très léger pour c # qui couvre toutes les bases.

Pour votre information, je suis l'auteur de SQL Data.

2
tjscience

Utilisez un ORM qui fonctionne comme SQL, mais fournit des vérifications à la compilation et une sécurité. J'aime mon préféré: Data Knowledge Objects (divulgation: je l'ai écrit)

Par exemple:

for (Bug bug : Bug.ALL.limit(100)) {
  int id = bug.getId();
  String title = bug.getTitle();
  System.out.println(id +" "+ title);
}

Entièrement en streaming. Facile à configurer (pas de mappages à définir - lit vos schémas existants). Prise en charge des jointures, des transactions, des requêtes internes, de l'agrégation, etc. Pratiquement tout ce que vous pouvez faire en SQL. Et a été prouvé à partir de jeux de données géants (séries chronologiques financières) tout en bas à trivial (Android).

1
keredson

L'une des applications que j'ai développées était un bot IRC) écrit en python. Les modules qu'il utilise s'exécutent dans des threads distincts, mais je n'ai pas trouvé de moyen de gérer les threads lorsque SQLite est utilisé. Bien que, cela pourrait être mieux pour une question distincte.

J'aurais vraiment dû simplement reformuler le titre et la question. Je n'ai jamais utilisé de DAL auparavant, dans aucune langue.

1
hydrapheetz

J'aimerais ajouter ma voix au choeur de réponses qui disent "Il y a un juste milieu!".

Pour un programmeur d'application, SQL est un mélange de choses que vous pouvez vouloir contrôler et de choses que vous ne voulez certainement pas être dérangé par le contrôle.

Ce que j’ai toujours voulu, c’est une couche (appelez-la DAL, ORM ou micro-ORM, cela ne me dérange pas de savoir laquelle) se chargera des décisions totalement prévisibles (comment épeler les mots-clés SQL, où se trouvent les parenthèses, quand inventer des alias de colonnes, quelles colonnes créer pour une classe qui contient deux floats et un int ...), tout en me laissant responsable des aspects de niveau supérieur du SQL, c’est-à-dire comment organiser les JOIN, les calculs côté serveur, DISTINCT, GROUP BY, sous-requêtes scalaires, etc.

J'ai donc écrit quelque chose qui fait ceci: http://quince-lib.com/

C'est pour le C++: je ne sais pas si c'est le langage que vous utilisez, mais il serait quand même intéressant de voir ceci prendre à quoi pourrait ressembler un "terrain d'entente".

1
slyqualin