web-dev-qa-db-fra.com

Normalisation MongoDB, clé étrangère et jointure

Avant de plonger très profondément dans MongoDB pendant des jours, je pensais que je poserais une question assez basique pour savoir si je devais plonger dedans ou pas. Je n'ai pratiquement aucune expérience avec nosql.

J'ai lu un peu sur certains des avantages des bases de données de documents, et je pense que pour cette nouvelle application, ils seront vraiment géniaux. C'est toujours compliqué de faire des favoris, des commentaires, etc. pour de nombreux types d'objets (beaucoup de relations m-à-m) et de sous-classes - c'est une sorte de douleur à gérer.

J'ai également une structure qui sera difficile à définir en SQL car elle est extrêmement imbriquée et se traduit par un document bien meilleur que 15 tableaux différents.

Mais je suis confus à propos de certaines choses.

  1. Est-il souhaitable de maintenir la normalisation de votre base de données? Je ne veux vraiment pas 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 ajoute un livre à ses favoris et que cette sélection est toujours 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 manuellement responsable de la suppression 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 (une sorte de jointure)? Dois-je faire une tolérance aux pannes ici?

64
egervari

MongoDB ne prend pas en charge les relations de clé étrangère côté serveur, la normalisation est également déconseillée. Vous devez 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 peut être alors moins rapide car DB doit effectuer des requêtes supplémentaires pour lire les objets mais permet une sorte de référence de clé étrangère.

Vous devrez toujours gérer vos références manuellement. Ce n'est qu'en regardant votre DBRef que vous verrez s'il existe, la DB ne parcourra pas tous les documents pour rechercher les références et les supprimera 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 vraiment difficile.

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 de bases de données MongoDB: Document Design for MongoDB

[~ # ~] mise à jour [~ # ~] 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 plusieurs pages, donc cela ne devrait pas être un problème d'en trouver.

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

63
Tomasz Stanczak

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 devez 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 ...

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

Dans l'autre classe de relations, deux entités existent indépendamment - ont des vies et des relations indépendantes. Mongo souhaite que ce type de relation n'existait pas, et il est frustrant de savoir précisément comment y faire face. L'intégration n'est tout simplement pas une solution. La normalisation n'est pas découragée ni encouragée. Mongo vous donne juste deux mécanismes pour y faire face; Références manuelles (analogue à une clé avec la contrainte de clé étrangère liant deux tables), et DBRef (une manière différente et légèrement plus structurée de faire de même). Dans ce cas d'utilisation, les bases de données SQL gagnent.

20
Francis M. Bacon