Lorsque vous utilisez un ORM, quelles sont les choses à surveiller dans la conception de votre base de données

19

Quels sont les problèmes de conception de base de données à surveiller lorsque vous savez que la base de données sera accessible à l'aide d'un mappeur relationnel objet (ORM) Wikipedia ? Voir également Entity Framework NHibernate ou LLBLGenPro.

À titre d'exemple, je noterai la limite de 2100 paramètres sur l'appel RPC de SqlServer. Il s'agit d'un problème lors de l'utilisation de LLBLgen et de la jonction de tables lorsque des clés primaires composées ont été utilisées, voir l'article MSDN pour les clés composées .

BozoJoe
la source
4
Aucune infraction, mais "joindre des tables avec plus d'une clé primaire" .. cela redéfinit l'une des règles de base d'une table, un seul PK par table. Que vouliez-vous dire exactement?
Marian
Comment cela atteint-il la limite des paramètres 2100? Avez-vous des tables avec autant de colonnes? En outre, je suppose que vous voulez dire "Cartographie objet-relationnelle" et non "Modélisation objet-rôle"
John Saunders
La limite de paramètre 2100 est parfois un problème si vous passez une grande liste de valeurs à un SQL 'IN' (tableau LINQ.Contains (membre)). Cependant, cela n'a rien à voir avec la conception de la base de données; c'est plus un problème de modèle de requête. La solution de contournement la plus simple pour les ORM qui en souffrent est d'insérer la liste dans une table temporaire [permanente] et de s'y joindre et / ou d'utiliser une sous-requête qui sélectionne les éléments à interroger d'où qu'ils proviennent. (passer des milliers d'éléments à un SQL "IN" est généralement mauvais de toute façon, que vous utilisiez un mappeur OR ou non).
KristoferA
@John, yes Object Relational Mapping
BozoJoe
4
@BozoJoe: une table ne peut - par définition - avoir qu'une seule clé primaire. Il n'y a aucun SGBD qui vous permettra de définir plus d'une clé primaire pour une seule table.
a_horse_with_no_name

Réponses:

17

Passez par des techniques de normalisation standard, principalement à la 3ème forme normale. Certains ORM peuvent reprendre les relations définies au niveau de la base de données, vous n'aurez donc pas à le faire manuellement.

Je voudrais vraiment aller dans l'autre sens et demander ce que dois-je savoir sur les ORM. Assurez-vous de savoir: - Comment profiler les requêtes? - Comment puis-je remplacer l'ORM et écrire ma propre requête? - Puis-je utiliser des proc stockés à la place?

La base de données doit être agnostique ORM car, plus que probable, elle survivra à l'application.

Eric Humphrey - lotsahelp
la source
+1: "La base de données doit être agnostique ORM". Respectez les normes de conception de base de données et les bons ORM seront également satisfaits.
MicSim
12
  1. Ne laissez jamais l'ORM créer ou mettre à jour le schéma. Utilisez toujours son SQL généré comme modèle mais parcourez-le avant de faire le changement (j'ai vu notre ORM faire des index redondants, utiliser de mauvais types de données ... toutes ces mauvaises choses)

  2. Soyez conscient de ce que votre ORM ne peut pas faire. Django pendant un certain temps n'a pas soutenu le groupe par le biais de l'ORM, ce qui était pénible (c'est toujours le cas, les systèmes hérités sont amusants!). Donc, être conscient des limites de l'ORM est un must pour le DBA même si ce n'est pas lui qui écrit le code de l'ORM

  3. Périodiquement, récupérez vos journaux lents, agrégez-les via mysqlslowlog et consultez le top 10 environ. Fondamentalement, il vous montrera les requêtes qui ont pris le plus de temps global. Une requête qui n'a pris en moyenne qu'une seconde mais a été exécutée 50 000 fois au cours du mois dernier se prolongerait sur ce rapport global comme un pouce endolori;)

Je ne dirais pas d'aller aussi extrême que de vider complètement l'ORM. Si vos développeurs utilisant l'ORM ne sont pas des DBA, ils sont susceptibles d'écrire du SQL aussi mauvais ou pire que l'ORM. Donc, finalement, il appartiendra au DBA de regarder ce qui se passe.

TechieGurl
la source
1
Et pensez à mettre une logique très complexe dans un proc stocké. Les ORM peuvent appeler des proc stockés et pour une logique très complexe, il est plus facile de régler les performances d'un proc.
HLGEM
7

Il y a quelques choses que je remarque tout de suite à propos d'une base de données héritée qui diffère d'une base de données créée par des ORM comme Sequel et ActiveRecord pour Ruby.

  1. L'utilisation d'une clé primaire dans toutes les tables appelées 'id'. Oui, cela peut être remplacé, mais idc'est la valeur par défaut.
  2. L'utilisation de plusieurs noms pour les tables.
  3. L'utilisation de traits de soulignement ("snakecase") pour séparer les mots créant le nom descriptif des tables et des champs.
  4. L'utilisation de _idclés ajoutées à des clés étrangères: la disposition est généralement similaire referenced_table_id.

J'écris mon SQL à la main depuis des années parce que je ne faisais pas confiance à un ORM, mais au cours des deux ou trois derniers, j'ai commencé à utiliser les deux ORM mentionnés précédemment, et je suis impressionné par la façon dont ils s'intègrent avec les bases de données existantes, et comment ils peuvent déchiffrer une base de données si leurs conventions sont respectées, ou je prends le temps de leur donner les conseils nécessaires pour comprendre une base de données héritée.

Je ne sais pas s'il existe des lignes directrices communes pour concevoir des schémas qui fonctionnent bien avec les ORM, mais je pense que nous aurions tous intérêt à avoir des normes. Il y a certainement un moment et un lieu pour un ORM, surtout si vous utilisez une bonne langue OO et que vous avez un horaire serré.

l'homme d'étain
la source
1
Pour info: il existe des outils pour gérer les différences de convention de dénomination pour de nombreux mappeurs OR. J'ai un complément pour Visual Studio qui s'occupe de cela pour Entity Framework et Linq-to-SQL avec une dénomination basée sur des règles; voir huagati.com/dbmltools pour plus de détails à ce sujet.
KristoferA
1
Id est un antipattern SQL pour nommer le champ id et ne doit pas être utilisé.
HLGEM
Vous voulez expliquer pourquoi? Comment gérer les relations entre les tables lorsque nous devons effectuer des recherches comme un à plusieurs et plusieurs à un? Dans les ORM que j'utilise, ne pas utiliser ID va définitivement à contre-courant.
le Tin Man
2

Cela dépend (:)) un peu du mappeur OR que vous utilisez, alors passez un peu de temps à rechercher quelles fonctionnalités de db le mappeur OR en question prend en charge / ne prend pas en charge.

Par exemple, les mappeurs OR de Microsoft ne prennent pas en charge tous les types de données intégrés de SQL Server, ne prennent pas en charge certaines des fonctionnalités TSQL plus récentes / avancées (requêtes récursives, conseils d'optimisation, etc.).

En théorie , un bon mappeur OR doit être suffisamment flexible pour surmonter (et vous permettre de mapper) un schéma de base de données relationnelle bien conçu à un bon modèle d'objet. En réalité, il nous reste encore un peu à faire avant que toutes les pièces du puzzle soient en place; bien que de nombreux mappeurs OR prennent en charge le mappage avancé, cela se fait souvent au détriment de requêtes complexes et de problèmes de performances.

Pour de bonnes performances de base de données (et pour préserver l'intégrité de la base de données :)), vous devez toujours suivre les meilleures pratiques en matière de conception de schéma de base de données; normaliser d'abord et dénormaliser là où [/ si] nécessaire. Côté code, n'allez pas trop loin avec votre modèle d'objet ; même si le mappeur OR prend en charge des modèles d'héritage complexes et des entités qui fusionnent de nombreuses tables ensemble, ce sont également les domaines où vous risquez de rencontrer des problèmes avec des requêtes trop complexes frappant la base de données, etc. Profil, profil, profil et ne pas simplement prendre l'ORM généré des requêtes pour acquis. Gardez à l'esprit que les requêtes générées par le mappeur OR peuvent souvent être modifiées comme les requêtes SQL normales et que deux requêtes fonctionnellement équivalentes du côté objet (par exemple les requêtes linq) peuvent parfois entraîner des requêtes SQL très différentes.

KristoferA
la source