68 votes

Normalisation, clé étrangère et jointure de MongoDB

Avant de me plonger dans MongoDB pendant plusieurs jours, j'ai pensé que je devais poser une question assez simple pour savoir si je devais m'y plonger ou non. Je n'ai pratiquement aucune expérience en matière de nosql.

J'ai lu quelques articles sur les avantages des bases de données documentaires, et je pense que pour cette nouvelle application, elles seront très utiles. Il est toujours fastidieux de faire des favoris, des commentaires, etc. pour de nombreux types d'objets (beaucoup de relations m-to-m) et de sous-classes - c'est un peu pénible à gérer.

J'ai également une structure qui sera difficile à définir en SQL parce qu'elle est extrêmement imbriquée et se traduit dans un document bien mieux que 15 tables différentes.

Mais je suis confus à propos de certaines choses.

  1. Est-il souhaitable de conserver une base de données normalisée ? Je ne veux vraiment pas avoir à mettre à jour plusieurs enregistrements. Est-ce toujours ainsi que les gens abordent la conception de la base de données dans MongoDB ?

  2. Que se passe-t-il lorsqu'un utilisateur sélectionne un livre et que cette sélection est encore stockée dans un document utilisateur, mais que le livre est ensuite supprimé ? Comment la relation se détache-t-elle sans clés étrangères ? Suis-je responsable de la suppression manuelle de tous les liens moi-même ?

  3. Que se passe-t-il si un utilisateur a favorisé un livre qui n'existe plus et que je l'interroge (par une sorte de jointure) ? Dois-je faire preuve de tolérance aux pannes ?

0 votes

Les bases de données SQL comme MySQL ne suppriment pas automatiquement les liens entre les tables, même lorsqu'elles sont reliées par une clé étrangère. La seule chose qu'elles font, c'est vous empêcher de supprimer une ligne dans une autre table connectée par clé étrangère, mais même là, c'est seulement si vous le leur demandez. Pourquoi pensez-vous que ce serait différent en NoSQL ?

5 votes

@trysis, google ON DELETE CASCADE.

2 votes

Oui, j'ai oublié pourquoi j'ai dit ça, c'était il y a si longtemps. Je m'excuse si j'ai induit quelqu'un en erreur avec mon ignorance passée.

65voto

Tomasz Stanczak Points 4790

MongoDB ne supporte pas les relations de clé étrangère côté serveur, la normalisation est également déconseillée. Vous devriez intégrer votre objet enfant dans les objets parents si possible, cela augmentera les performances et rendra les clés étrangères totalement inutiles. Cela dit, ce n'est pas toujours possible, il existe donc une construction spéciale appelée DBRef qui permet de référencer des objets dans une collection différente. Cela n'est pas toujours très rapide car la base de données doit effectuer des requêtes supplémentaires pour lire les objets, mais cela permet une sorte de référence à une clé étrangère.

Vous devrez néanmoins gérer vos références manuellement. C'est seulement en recherchant votre DBRef que vous verrez si elle existe, la DB ne va pas parcourir tous les documents pour rechercher les références et les supprimer si la cible de la référence n'existe plus. Mais je pense que la suppression de toutes les références après la suppression du livre nécessiterait une seule requête par collection, pas plus, donc pas si difficile que ça.

Si votre schéma est plus complexe, vous devriez probablement choisir une base de données relationnelle et non nosql.

Il existe également un livre sur la conception des bases de données MongoDB : Conception de documents pour MongoDB

UPDATE Le livre ci-dessus n'est plus disponible, mais en raison de la popularité de MongoDB, il y en a beaucoup d'autres. Je ne les lierai pas tous, car ces liens sont susceptibles de changer, une simple recherche sur Amazon montre de nombreuses pages, il ne devrait donc pas être difficile d'en trouver.

Consultez la page de manuel de MongoDB pour Références manuelles" et DBRefs pour plus de détails et d'exemples

0 votes

Merci beaucoup pour la réponse ! En fait, je pense que ce projet est suffisamment important pour qu'une base de données relationnelle soit la meilleure option maintenant. Dans cette application, il va y avoir beaucoup de références et cela va prendre plusieurs requêtes dans de nombreux cas. Cela n'en vaut pas la peine.

1 votes

Le livre mentionné dans le post n'est plus disponible sur Amazon. Savez-vous si ce livre a été remplacé par un autre ?

0 votes

J'ai trouvé celui-ci : shop.oreilly.com/product/0636920001096.do il contient probablement des informations utiles, au cas où il ne s'agirait pas du même livre réédité.

25voto

Francis M. Bacon Points 628

Ci-dessus, @TomaaszStanczak déclare

MongoDB ne prend pas en charge les relations de clé étrangère côté serveur, la normalisation est également déconseillée. Vous devriez intégrer votre objet enfant à l'intérieur d'objets parents si possible, cela augmentera les performances et performances et rendra les clés étrangères totalement inutiles. Cela dit, ce n'est pas toujours possible ...

La normalisation n'est pas découragée par Mongo. Pour être clair, nous parlons de deux types de relations fondamentalement différentes que peuvent avoir deux entités de données. Dans l'une, une entité enfant est appartenant à exclusivement par un objet parent. Dans ce type de relation, la méthode Mongo consiste à intégrer.

Dans l'autre catégorie de relations, deux entités existent indépendamment - elles ont des durées de vie et des relations indépendantes. Mongo souhaiterait que ce type de relation n'existe pas, et il est frustrant de constater qu'il ne dit rien sur la manière précise de la traiter. L'incorporation n'est tout simplement pas une solution. La normalisation n'est ni découragée, ni encouragée. Mongo vous propose simplement deux mécanismes pour y faire face ; Refs manuels (analogue à une clé avec la contrainte de la clé étrangère liant deux tables), et DBRef (une manière différente, légèrement plus structurée, de faire la même chose). Dans ce cas d'utilisation, les bases de données SQL sont gagnantes.

3 votes

+1 Accepté. Des citations sur Internet comme "En général, dans MongoDB, vous voudriez stocker les données de la manière dont l'application y accède, éliminant ainsi le besoin de jointures" sont courantes, mais votre point sur la propriété exclusive et la stabilité déduite des données est souvent négligé.

1voto

dougB Points 202

Les réponses de Tomasz et Francis contiennent de bons conseils : la "normalisation" n'est pas découragée par Mongo, mais vous devriez d'abord envisager d'optimiser la conception des documents de votre base de données avant de créer des "références de documents". DBRefs ont été mentionnées par Tomasz, mais comme il y a fait allusion, elles ne sont pas une "solution miracle" et nécessitent un traitement supplémentaire pour être utiles.

Ce qui est maintenant possible, à partir de la version 3.2 de MongoDB, est de produire des résultats équivalents à un SQL JOIN en utilisant le $lookup opérateur d'étape du pipeline d'agrégation. De cette manière, vous pouvez avoir une structure de document "normalisée", tout en étant capable de produire des résultats consolidés. Pour que cela fonctionne, vous devez créer une clé unique dans la collection cible qui, espérons-le, sera à la fois significatif y unique . Vous pouvez renforcer l'unicité en créant un index unique sur ce champ.

$lookup est assez simple à utiliser. Jetez un coup d'œil à la documentation ici : https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#lookup-aggregation . Exécuter le aggregate() sur la collection source (c'est-à-dire la table "gauche"). Le site de Le paramètre est la collection cible (c'est-à-dire la "bonne" table). Le site localField est le champ de la collection source (c'est-à-dire la "clé étrangère"). L'adresse ForeignField sera le champ correspondant dans la collection cible.

En ce qui concerne les documents orphelins, d'après votre question, je suppose que vous pensez à un ensemble de contraintes traditionnelles du SGBDR, à des suppressions en cascade, etc. Là encore, à partir de la version 3.2 de MongoDB, il existe une prise en charge native des contraintes suivantes validation des documents . Jetez un coup d'œil à cet article de StackOver : Comment appliquer des contraintes dans MongoDB ? Regardez la deuxième réponse, de JohnnyHK

Packt Publishers propose un grand nombre de bons livres sur MongoDB. (Divulgation complète : j'ai écrit quelques-uns d'entre eux).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X