Je viens de tomber sur cette question et, bien qu'elle soit ancienne, j'ai pensé qu'il serait utile d'ajouter quelques possibilités non mentionnées dans les réponses données. De plus, les choses ont un peu évolué ces dernières années, il convient donc de souligner que SQL et NoSQL se rapprochent l'un de l'autre.
Un des commentateurs a évoqué la sage attitude de prudence selon laquelle «si les données sont relationnelles, utilisez relationnelles». Cependant, ce commentaire n'a de sens que dans le monde relationnel, où les schémas viennent toujours avant l'application.
MONDE RELATIONNEL: Structurer les données> Ecrire une application pour l'obtenir
NOSQL WORLD: Concevoir une application> Structurer les données en conséquence
Même si les données sont relationnelles, NoSQL reste une option. Par exemple, les relations un-à-plusieurs ne posent aucun problème et sont largement couvertes dans la documentation MongoDB
UNE SOLUTION 2015 À UN PROBLÈME DE 2010
Depuis que cette question a été publiée, il y a eu de sérieuses tentatives pour rapprocher noSQL de SQL. L'équipe dirigée par Yannis Papakonstantinou à l'Université de Californie (San Diego) a travaillé sur FORWARD , une implémentation de SQL ++ qui pourrait bientôt être la solution à des problèmes persistants comme celui posté ici.
À un niveau plus pratique, la sortie de Couchbase 4.0 a signifié que, pour la première fois, vous pouvez faire des JOIN natifs dans NoSQL. Ils utilisent leur propre N1QL. Voici un exemple d'un JOIN
de leurs tutoriels :
SELECT usr.personal_details, orders
FROM users_with_orders usr
USE KEYS "Elinor_33313792"
JOIN orders_with_users orders
ON KEYS ARRAY s.order_id FOR s IN usr.shipped_order_history END
N1QL permet la plupart sinon toutes les opérations SQL, y compris l'agrégation, le filtrage, etc.
LA SOLUTION HYBRIDE PAS SI NOUVELLE
Si MongoDB est toujours la seule option, alors j'aimerais revenir sur mon point selon lequel l'application doit avoir priorité sur la structure des données. Aucune des réponses ne mentionne l'incorporation hybride, dans laquelle la plupart des données interrogées sont incorporées dans le document / objet et les références sont conservées pour une minorité de cas.
Exemple: des informations (autres que le nom du rôle) peuvent-elles attendre? Le démarrage de l'application pourrait-il être plus rapide en ne demandant rien dont l'utilisateur n'a pas encore besoin?
Cela pourrait être le cas si l'utilisateur se connecte et qu'il / elle a besoin de voir toutes les options pour tous les rôles auxquels il appartient. Cependant, l'utilisateur est un «ingénieur» et les options pour ce rôle sont rarement utilisées. Cela signifie que l'application n'a besoin que d'afficher les options pour un ingénieur au cas où il / elle voudrait cliquer dessus.
Ceci peut être réalisé avec un document qui indique à l'application au début (1) à quels rôles l'utilisateur appartient et (2) où obtenir des informations sur un événement lié à un rôle particulier.
{_id: ObjectID(),
roles: [[“Engineer”, “ObjectId()”],
[“Administrator”, “ObjectId()”]]
}
Ou, mieux encore, indexez le champ role.name dans la collection de rôles, et vous n'aurez peut-être pas besoin d'incorporer ObjectID () non plus.
Autre exemple: des informations sur TOUS les rôles sont-elles demandées TOUT le temps?
Il peut également arriver que l'utilisateur se connecte au tableau de bord et exécute 90% du temps des tâches liées au rôle «Ingénieur». L'intégration hybride pourrait être effectuée pour ce rôle particulier dans son intégralité et ne conserver que les références pour le reste.
{_id: ObjectID(),
roles: [{name: “Engineer”,
property1: value1,
property2: value2
},
[“Administrator”, “ObjectId()”]
]
}
Être sans schéma n'est pas seulement une caractéristique de NoSQL, cela pourrait être un avantage dans ce cas. Il est parfaitement valable d'imbriquer différents types d'objets dans la propriété «Roles» d'un objet utilisateur.