Utiliser un ORM ou un SQL simple?

Pour certaines des applications que j’ai développées (puis a commencé à oublier), j’écris du code SQL simple, principalement pour MySQL. Bien que j’aie utilisé des ORM en python comme SQLAlchemy , je ne les ai pas utilisés longtemps. En général, c’était la documentation ou la complexité (de mon sharepoint vue) qui me retenait.

Je le vois comme ceci: utilisez un ORM pour la portabilité, du SQL simple si vous voulez utiliser un seul type de firebase database. Je cherche vraiment des conseils sur l’utilisation d’un ORM ou d’un SQL lors du développement d’une application nécessitant un support de firebase database.

En y repensant, il serait préférable d’utiliser un wrapper léger pour gérer les incohérences de la firebase database par rapport à l’utilisation d’un ORM.

Les ORM ont quelques fonctionnalités intéressantes. Ils peuvent gérer une grande partie du travail de copie de colonnes de firebase database dans les champs d’object. Ils gèrent généralement la conversion des types de date et d’heure du langage vers le type de firebase database approprié. Ils traitent généralement les relations un à plusieurs de manière assez élégante en instanciant des objects nesteds. J’ai trouvé que si vous concevez votre firebase database avec les forces et les faiblesses de l’ORM en tête, cela économise beaucoup de travail pour obtenir et extraire des données de la firebase database. (Vous voudrez savoir comment il gère le polymorphism et les relations plusieurs-à-plusieurs si vous avez besoin de les mapper. Ce sont ces deux domaines qui fournissent la plupart des «incompatibilités d’impédance» qui appellent ORM le vietnam de l’informatique. .)

Pour les applications transactionnelles, c’est-à-dire que vous effectuez une requête, récupérez des objects, les parcourez pour obtenir des données et les restituer sur une page Web, la taxe sur les performances est faible et dans de nombreux cas, ORM vu auparavant, cela aurait autrement demandé à la firebase database plusieurs fois.

Pour les applications à forte charge de génération de rapports ou qui traitent un grand nombre de lignes de firebase database par demande, la taxe ORM est beaucoup plus lourde et leur mise en cache devient une lourde charge inutile pour la mémoire. Dans ce cas, le mappage SQL simple (LinQ ou iBatis) ou les requêtes SQL codées à la main dans une couche DAL mince sont la solution.

J’ai trouvé pour toute application à grande échelle que vous utiliserez les deux approches. (ORM pour les CRUD simples et SQL / thin DAL pour les rapports).

En tant que personne ayant passé pas mal de temps à travailler avec JPA (API Java Persistence, essentiellement l’API ORM standardisée pour Java / J2EE / EJB), incluant Hibernate, EclipseLink, Toplink, OpenJPA et d’autres, je partagerai observations.

  1. Les ORM ne sont pas rapides. Ils peuvent être adéquats et la plupart du temps, ils sont corrects, mais dans un environnement à faible latence et à volume élevé, ils sont un non-non;
  2. Dans les langages de programmation à usage général comme Java et C #, vous avez besoin de beaucoup de magie pour les faire fonctionner (par exemple, le temps de 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 passé à peaufiner le XML et / ou les annotations / atsortingbuts pour que votre ORM génère du SQL performant;
  4. Pour les requêtes complexes, il n’y a pas de substitut. Comme dans JPA, certaines requêtes ne sont tout simplement pas possibles en SQL brut et lorsque vous devez utiliser du SQL brut dans JPA, ce n’est pas beau (C # /. Net a au moins des types dynamics – var – ce qui est beaucoup plus beau qu’un tableau Object);
  5. Il y a énormément de “pièges” lors de l’utilisation des ORM. Cela inclut un comportement involontaire ou inattendu, le fait que vous devez intégrer la possibilité d’effectuer des mises à jour SQL dans votre firebase database (en utilisant refresh () dans JPA ou des méthodes similaires, car JPA met par défaut tout en mémoire cache). update – exécuter des mises à jour SQL directes est une activité de support de production commune;
  6. L’inadéquation relationnelle des objects va toujours causer des problèmes. Avec un tel problème, il y a un compromis entre la complexité et l’exhaustivité de l’abstraction. À certains moments, j’ai senti que JPA était allée trop loin et avait atteint une véritable loi de rendements décroissants où la complexité n’était pas justifiée par l’abstraction.

Il y a un autre problème qui prend un peu plus d’explications.

Le modèle traditionnel d’une application Web consiste à disposer d’une couche de persistance et d’une couche de présentation (éventuellement avec des services ou d’autres couches, mais ce sont les deux éléments importants de cette discussion). Les ORM forcent une vue rigide de votre couche de persistance à la couche de présentation (vos entités).

Une des critiques à l’égard des méthodes SQL plus brutes est que vous vous retrouvez avec toutes ces VO (objects de valeur) ou ces DTO (objects 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.

Ces problèmes ne disparaissent pas avec les ORM, ils remontent simplement dans la couche de présentation. Au lieu de créer des VO / DTO pour les requêtes, vous créez des objects de présentation personnalisés, généralement un pour chaque vue. Comment ça va mieux? IMHO ce n’est pas.

J’ai écrit à ce sujet dans ORM ou SQL: sums-nous déjà là? .

Ma technologie de persistance de choix (en Java) est aujourd’hui ibatis. Il s’agit d’une solution très fine qui permet de réaliser 90% de ce que JPA peut faire (elle peut même effectuer un chargement différé des relations, bien qu’elle ne soit pas bien documentée), mais avec beaucoup moins de complexité et de code.

Cela est arrivé l’année dernière dans une application GWT que j’écrivais. Beaucoup de traduction d’EclipseLink vers des objects de présentation dans l’implémentation du service. Si nous utilisions ibatis, il aurait été beaucoup plus simple de créer les objects appropriés avec ibatis, puis de les passer tout au long de la stack. Certains puristes pourraient soutenir que c’est Bad ™. Peut-être que oui (en théorie) mais je vous dis quoi: cela aurait conduit à un code plus simple, à une stack plus simple et à une productivité accrue.

Je dis SQL simple pour R eads, ORM pour CUD .

Je suis toujours préoccupé par les performances, en particulier dans les applications Web, mais aussi dans la maintenance et la lisibilité du code. Pour résoudre ces problèmes, j’ai écrit SqlBuilder .

L’ORM n’est pas simplement la portabilité (ce qui est difficile à réaliser, même avec les ORM). Cela vous donne essentiellement une couche d’abstraction sur un stockage persistant, lorsqu’un outil ORM vous libère de l’écriture de requêtes SQL complexes (sélection par PK ou par prédicats, insertions, mises à jour et suppressions) et vous permet de vous concentrer sur le problème.

Toute conception respectable nécessitera une abstraction pour la firebase database, juste pour gérer la non-concordance d’impédance. Mais la première étape la plus simple (et adéquate dans la plupart des cas) serait sans doute un DAL, pas un ORM lourd. Vos seules options ne sont pas celles situées aux extrémités du spectre.


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

Une DAL est ce que vous écrivez vous-même, peut-être à partir d’une classe qui encapsule simplement une table et mappe ses champs aux propriétés. Un ORM est du 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 à fuir ou non. Je préfère les informer intentionnellement, mais cela peut être ma préférence personnelle).

Chaque outil a son but et sa vision. J’ai créé http://www.jooq.org/ pour répondre exactement à vos besoins, même si iBatis est probablement une bonne solution pour vous.

JOOQ a des fonctionnalités ORM de base, mais il se concentre principalement sur les choses dont la plupart des développeurs ont besoin, lorsque j’essaie de trouver le meilleur ORM pour leurs besoins:

  • génération de code
  • liaison de 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, vous ne penseriez pas qu’ils courent contre un SGBDR. Par contre, vous avez choisi un SGBDR précisément parce que

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

JOOQ répond exactement à ces points. Il fonctionnera aussi bien que JDBC, mais sans douleur.

La génération de code a été la clé de l’utilisation de l’ORM. Je suis d’accord que l’itinéraire ORM n’est pas le plus rapide, en termes de performance du code. Mais lorsque vous avez une équipe de taille moyenne à grande, la firebase database change rapidement la capacité de régénérer les classes et les mappages à partir de la firebase database dans le cadre du processus de construction. 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 l’utilisation d’un ORM alors que le schéma est encore fluide, d’utiliser le profilage pour trouver les goulots d’étranglement, puis de régler les zones qui en ont besoin à l’aide de SQL brut.

Une autre pensée, la mise en cache intégrée à Hibernate peut souvent apporter des améliorations de performances massives si elle est utilisée correctement. Plus besoin de revenir au DB pour lire les données de référence.

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

Ce qu’il importe de comprendre, c’est que chaque framework ou approche a ses avantages et ses inconvénients. Par exemple, dans notre expérience, nous avons constaté que l’ORM est utile lorsqu’il s’agit de résultats il est 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 sélectionner un cadre ou une approche et de tout mettre en œuvre. Ce que nous entendons par là, c’est que nous pouvons combiner ORM et langage de requête natif. De nombreux frameworks ORM donnent 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 frameworks ou approches et proposer une solution appropriée.

Vous pouvez utiliser ORM pour l’insertion, la mise à jour, la suppression et le contrôle de version avec un niveau élevé de concurrence. Vous pouvez également utiliser Native SQL pour la génération de rapports et la création de listes longues.

Il n’y a pas de solution «one-tool-fits-all», et cela est également vrai pour la question «dois-je utiliser un ou / m ou non? ‘.

Je dirais: si vous devez écrire une application / un outil qui est très «centré sur les données», sans trop d’autre logique, j’utiliserais alors du langage SQL, car SQL est le langage spécifique à ce type d’applications.

En revanche, si je devais écrire une application métier / d’entreprise contenant beaucoup de logique de domaine, j’écrirais un modèle de classe riche qui pourrait exprimer ce domaine en code. Dans un tel cas, un mappeur OR / M peut être très utile pour réussir, car il vous prend beaucoup de code de plomberie.

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

Jetez un coup d’oeil aux données SQL ( http://sqldata.codeplex.com ). C’est un ORM très léger pour c # qui couvre toutes les bases.

Pour info, je suis l’auteur de SQL Data.

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 lors de l’utilisation de sqlite. Cependant, cela pourrait être mieux pour une question distincte.

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

Utilisez un ORM qui fonctionne comme SQL, mais fournit des contrôles au moment de la compilation et tapez la sécurité. Comme 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(); Ssortingng title = bug.getTitle(); System.out.println(id +" "+ title); } 

Entièrement en streaming. Facile à configurer (pas de cartographie à définir – lit vos schémas existants). Prend en charge les jointures, les transactions, les requêtes internes, l’agrégation, etc. À peu près 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) jusqu’à sortingvial (Android).

J’aimerais append ma voix au refrain de réponses qui disent “Il y a un terrain d’entente!”.

Pour un programmeur d’application, SQL est un mélange de choses que vous voudrez peut-être contrôler et de choses que vous ne voudrez probablement pas déranger en contrôlant.

Ce que j’ai toujours voulu, c’est une couche (appelez-la DAL, ORM ou micro-ORM, qui ne me dérange pas) qui prendra en charge les décisions totalement prévisibles (comment épeler les mots-clés SQL, où les parenthèses vont, quand inventer des alias de colonne, quelles colonnes créer pour une classe contenant deux flottants et un int …), tout en me chargeant des aspects de haut niveau du SQL, à savoir comment organiser les JOIN, les calculs côté serveur, DISTINCT, GROUP BYs, sous-requêtes scalaires, etc.

Donc j’ai écrit quelque chose qui fait ça: http://quince-lib.com/

C’est pour C ++: je ne sais pas si c’est le langage que vous utilisez, mais il serait peut-être intéressant de voir à quoi pourrait ressembler un “moyen terme”.