J'essaie de comprendre l'équivalent des clés étrangères et des index dans les bases de données NoSQL KVP ou Document. Puisqu'il n'y a pas de tableaux croisés dynamiques (pour ajouter des clés marquant une relation entre deux objets), je suis vraiment perplexe quant à la façon dont vous pourriez récupérer des données d'une manière qui serait utile pour les pages Web normales.
Disons que j'ai un utilisateur, et cet utilisateur laisse de nombreux commentaires sur tout le site. Le seul moyen auquel je pense pour suivre les commentaires des utilisateurs est de
- Intégrez-les dans l'objet utilisateur (ce qui semble assez inutile)
- Créez et maintenez une
user_id:comments
valeur qui contient une liste de la clé de chaque commentaire [commentaire: 34, commentaire: 197, etc ...] afin que je puisse les récupérer si nécessaire.
Cependant, en prenant le deuxième exemple, vous allez bientôt heurter un mur de briques lorsque vous l'utilisez pour suivre d'autres choses comme une clé appelée "active_comments" qui peut contenir 30 millions d'identifiants, ce qui coûte une TONNE d'interroger chaque page juste pour en savoir plus commentaires actifs. Il serait également très sujet aux conditions de course, car de nombreuses pages pourraient essayer de le mettre à jour en même temps.
Comment puis-je suivre des relations comme les suivantes dans une base de données NoSQL?
- Tous les commentaires d'un utilisateur
- Tous les commentaires actifs
- Tous les messages tagués avec [mot-clé]
- Tous les étudiants d'un club - ou tous les clubs auxquels appartient un étudiant
Ou est-ce que je pense mal à cela?
la source
Réponses:
Toutes les réponses pour savoir comment stocker des associations plusieurs-à-plusieurs de la «manière NoSQL» se résument au même: stocker les données de manière redondante.
Dans NoSQL, vous ne concevez pas votre base de données en fonction des relations entre les entités de données. Vous concevez votre base de données en fonction des requêtes que vous exécuterez sur elle. Utilisez les mêmes critères que vous utiliseriez pour dénormaliser une base de données relationnelle: s'il est plus important que les données aient une cohésion (pensez aux valeurs dans une liste séparée par des virgules au lieu d'une table normalisée), alors faites-le de cette façon.
Mais cela optimise inévitablement pour un type de requête (par exemple les commentaires de tout utilisateur pour un article donné) au détriment d'autres types de requêtes (commentaires pour tout article par un utilisateur donné). Si votre application a besoin que les deux types de requêtes soient également optimisés, vous ne devez pas dénormaliser. Et de même, vous ne devez pas utiliser de solution NoSQL si vous devez utiliser les données de manière relationnelle.
La dénormalisation et la redondance risquent de voir des ensembles de données redondants se désynchroniser les uns avec les autres. C'est ce qu'on appelle une anomalie . Lorsque vous utilisez une base de données relationnelle normalisée, le SGBDR peut éviter les anomalies. Dans une base de données dénormalisée ou en NoSQL, il devient de votre responsabilité d'écrire le code de l'application pour éviter les anomalies.
On pourrait penser que ce serait formidable pour une base de données NoSQL de faire le dur travail de prévention des anomalies pour vous. Il existe un paradigme qui peut faire cela - le paradigme relationnel.
la source
L'approche couchDB suggère d'émettre des classes appropriées de trucs dans la phase de carte et de les résumer en réduire. Ainsi, vous pouvez mapper tous les commentaires et émettre
1
pour l'utilisateur donné et en imprimer plus tard seulement. Il faudrait cependant beaucoup de stockage sur disque pour créer des vues persistantes de toutes les données traçables dans couchDB. btw ils ont aussi cette page wiki sur les relations: http://wiki.apache.org/couchdb/EntityRelationship .Riak, d'autre part, a un outil pour construire des relations. C'est un lien. Vous pouvez saisir l'adresse d'un document lié (ici commentaire) dans le document «racine» (ici document utilisateur). Il a un truc. S'il est distribué, il peut être modifié en une seule fois dans de nombreux endroits. Cela provoquera des conflits et par conséquent un énorme arbre d'horloge vectorielle: / ..pas si mal, pas si bon.
Riak a également un autre «mécanisme». Il dispose d'un espace de nom de clé à 2 couches, appelé seau et clé. Ainsi, par exemple étudiant, si nous avons les clubs A, B et C et étudiant StudentX, StudentY, vous pouvez maintenir la convention suivante:
et pour lire la relation, il suffit de lister les clés dans des compartiments donnés. Qu'est-ce qui ne va pas avec ça? C'est sacrément lent. La liste des seaux n'a jamais été une priorité pour riak. Cela va de mieux en mieux. btw. vous ne gaspillez pas de mémoire car cet exemple
{true}
peut être lié à un seul profil complet de StudentX ou Y (ici les conflits ne sont pas possibles).Comme vous le voyez NoSQL! = NoSQL. Vous devez examiner une implémentation spécifique et la tester par vous-même.
Mentionné avant Les magasins de colonnes semblent bien adaptés aux relations .. mais tout dépend de vos besoins A, C et P;) Si vous n'avez pas besoin de A et que vous avez moins de Peta octets, laissez-le simplement, continuez avec MySql ou Postgres.
bonne chance
la source
user: userid: comments est une approche raisonnable - pensez-y comme l'équivalent d'un index de colonne en SQL, avec l'exigence supplémentaire que vous ne pouvez pas interroger sur les colonnes non indexées.
C'est là que vous devez réfléchir à vos besoins. Une liste de 30 millions d'articles n'est pas déraisonnable parce qu'elle est lente, mais parce qu'il est impossible d'en faire quoi que ce soit. Si votre véritable exigence est d'afficher des commentaires récents, vous feriez mieux de garder une liste très courte qui est mise à jour chaque fois qu'un commentaire est ajouté - rappelez-vous que NoSQL n'a aucune exigence de normalisation. Les conditions de concurrence sont un problème avec les listes dans un magasin de valeurs de clés de base, mais généralement, soit votre plate-forme prend en charge correctement les listes, vous pouvez faire quelque chose avec des verrous, ou vous ne vous souciez pas réellement des mises à jour qui ont échoué.
Idem que pour les commentaires des utilisateurs - créez un mot-clé d'index: posts
Plus de la même chose - probablement une liste des clubs en tant que propriété de l'étudiant et un index sur ce domaine pour obtenir tous les membres d'un club
la source
Tu as
Eh bien, dans une base de données relationnelle, la chose normale à faire serait de normaliser les données dans une relation un-à-plusieurs. C'est la même chose que vous feriez dans une base de données NoSQL. Indexez simplement les champs avec lesquels vous allez récupérer les informations.
Par exemple, les index importants pour vous sont
Si vous utilisez NosDB (une base de données NoSQL basée sur .NET avec prise en charge SQL), vos requêtes seront comme
Vérifiez tous les types de requêtes pris en charge à partir de leur aide-mémoire SQL ou de leur documentation.
la source