Question

De nombreux "BAW" (gros sites Web) utilisent des techniques de stockage et de récupération de données qui s'appuient sur d'énormes tables avec des index, et utilisent des requêtes qui ne veulent/ne peuvent pas utiliser de JOIN dans leurs requêtes (BigTable, HQL, etc.) pour gérer l'évolutivité et le partitionnement des bases de données.Comment cela fonctionne-t-il lorsque vous disposez de très nombreuses données très en rapport?

Je ne peux que spéculer sur le fait qu'une grande partie de cette adhésion doit se faire du côté des applications, mais cela ne commence-t-il pas à devenir coûteux ?Que se passe-t-il si vous devez effectuer plusieurs requêtes sur plusieurs tables différentes pour obtenir des informations à compiler ?Est-ce que le fait d'accéder à la base de données plusieurs fois ne commence pas à coûter plus cher que de simplement utiliser des jointures en premier lieu ?Je suppose que cela dépend de la quantité de données dont vous disposez ?

Et pour les ORM couramment disponibles, comment ont-ils tendance à gérer l’impossibilité d’utiliser les jointures ?Existe-t-il une prise en charge pour cela dans les ORM qui sont aujourd'hui très utilisés ?Ou la plupart des projets qui doivent approcher ce niveau de données ont-ils tendance à se lancer de toute façon ?

Cela ne s'applique donc à aucun projet que je réalise actuellement, mais c'est quelque chose qui me trotte dans la tête depuis plusieurs mois maintenant et je ne peux que spéculer sur ce que sont les "meilleures pratiques".Je n’ai jamais eu besoin d’aborder ce problème dans aucun de mes projets car ils n’ont jamais atteint une échelle où cela était requis.J'espère que cette question aidera également d'autres personnes.

Comme quelqu'un l'a dit ci-dessous, les ORM "ne fonctionnent pas" sans jointures.Existe-t-il d'autres couches d'accès aux données déjà disponibles pour les développeurs travaillant avec des données à ce niveau ?

MODIFIER:Pour quelques précisions, Vinko Vrsalovic dit:

"Je crois que Snicker veut parler de non-SQL, où les données transactionnelles sont dénormalisées et utilisées dans les régimes Hadoop ou BigTable ou Cassandra."

C'est effectivement de cela dont je parle.

Des points bonus pour ceux qui attrapent la référence xkcd.

Était-ce utile?

La solution

La façon dont je regarde, une base de données relationnelle est un outil polyvalent pour couvrir vos paris. Les ordinateurs modernes sont assez rapides, et SGBDR » sont assez bien optimisés que vous pouvez atteindre une taille respectable tout à fait sur une seule boîte. En choisissant un SGBDR vous vous donnez un accès très flexible à vos données, et la capacité d'avoir de puissantes contraintes d'exactitude qui le rendent beaucoup plus facile à coder par rapport aux données. Cependant, le SGBDR ne va pas représenter une bonne optimisation pour tout problème particulier, il vous donne juste la possibilité de changer facilement les problèmes.

Si vous commencez à croissance rapide et réalisez que vous allez avoir à l'échelle au-delà de la taille d'un seul serveur DB, vous avez soudainement des choix beaucoup plus difficile à faire. Vous aurez besoin de commencer à identifier les goulots d'étranglement et de les supprimer. Le SGBDR va être un nœud gronda méchant de codépendance que vous aurez à démêler. Plus vos données reliées entre elles le plus de travail que vous aurez à faire, mais peut-être que vous n'aurez pas à démêler complètement la chose. Si vous êtes peut-être lu-lourd, vous pouvez obtenir avec la réplication simple. Si vous saturant votre marché et la croissance se stabilise, vous pouvez peut-être partiellement dénormaliser et tesson à nombre fixe de serveurs DB. Peut-être vous avez juste une poignée de tables de problèmes qui peuvent être déplacés dans un magasin de données plus évolutive. Peut-être que votre profil d'utilisation est en cache très convivial et vous pouvez simplement migrer la charge à un cluster memcached géant.

Lorsque des magasins de clé-valeur évolutives comme BigTable sont disponibles en est quand aucun des ci-dessus peut travailler, et vous avez tellement de données d'un seul type que même quand il est dénormaliser une seule table est trop pour un seul serveur. À ce stade, vous devez être en mesure de partitionner ont arbitrairement et encore une API propre pour y accéder. Bien entendu lorsque les données sont réparties sur autant de machines que vous ne pouvez pas avoir des algorithmes qui ont besoin de ces machines pour se parler beaucoup, dont beaucoup des algorithmes standards relationnels nécessiterait. Comme vous le suggérez, ces algorithmes d'interrogation distribués ont le potentiel d'exiger plus de puissance de traitement totale que l'équivalent JOIN dans une base de données relationnelle correctement indexé, mais parce qu'ils sont parallélisés les performances en temps réel est des ordres de grandeur mieux que toute seule machine pourrait faire (en supposant une machine qui pourrait tenir l'index entier existe même).

Maintenant, une fois que vous pouvez redimensionner vos données massives placé horizontalement (simplement en branchant plusieurs serveurs), la partie dure de l'évolutivité est fait. Eh bien, je ne devrais pas dire fait , parce que les opérations en cours et le développement à cette échelle sont beaucoup plus difficile que l'application serveur unique, mais le point est des serveurs d'applications sont généralement trivial à l'échelle via un partage rien l'architecture aussi longtemps qu'ils peuvent obtenir les données dont ils ont besoin en temps opportun.

Pour répondre à votre question sur la façon dont les ORM couramment utilisés gérer l'impossibilité d'utiliser JOIN, la réponse est ils ne le font pas . ORM signifie Object Relational Mapping, et la plupart du travail d'un ORM est tout simplement traduire le puissant paradigme relationnel des structures de données orientées objet simples prédicat logiques. La plupart de la valeur de ce qu'ils vous donnent est tout simplement ne va pas être possible à partir d'un magasin clé-valeur. En pratique, vous aurez probablement besoin de construire et maintenir votre propre couche d'accès aux données qui est adapté à vos besoins particuliers, car les profils de données à ces échelles vont varier considérablement et je crois qu'il ya trop de compromis pour un outil d'usage général pour sortir et devenir dominant la voie SGBDR ont. En bref, vous aurez toujours à faire plus travail sur le terrain à cette échelle.

Cela dit, il sera certainement intéressant de voir quel genre de fonctionnalités relationnelles ou autre agrégat peut être construit sur des primitives de magasin clé-valeur. Je n'ai pas vraiment assez d'expérience ici pour commenter spécifiquement, mais il y a beaucoup de connaissances dans l'entreprise computing sur ce qui remontent à plusieurs années (par exemple. Oracle), beaucoup de connaissances théoriques inexploitées dans le monde universitaire, beaucoup de connaissances pratiques sur Google, Amazon, Facebook, et al, mais la connaissance qui a filtré dans la communauté du développement est encore assez limitée.

Cependant, maintenant que beaucoup d'applications se déplacent sur le Web, et de plus en plus de la population mondiale est en ligne, inévitablement plus d'applications et plus auront à l'échelle, et les meilleures pratiques commencent à se cristalliser. L'écart de connaissances sera amenuisé des deux côtés par des services de cloud computing comme AppEngine et EC2, ainsi que des bases de données open source comme Cassandra. Dans un certain sens, cela va de pair avec le calcul parallèle et asynchrone qui est à ses débuts. Sans aucun doute un moment fascinant d'être un programmeur.

Autres conseils

Vous en partant d'une hypothèse erronée.

L'entreposage de données ne normalise pas les données de la même manière qu'une application de transaction normalise. Il n'y a pas « beaucoup » de jointures. Il y a relativement peu.

En particulier deuxième et troisième violations de forme normale ne sont pas un « problème », puisque les entrepôts de données sont rarement mises à jour. Et quand ils sont mis à jour, il est généralement seulement un changement de drapeau d'état pour faire une lignes de dimension en « courant » vs « pas à jour ».

Puisque vous n'avez pas à vous soucier des mises à jour, vous ne se décomposent pas les choses au niveau 2FN où une mise à jour ne peut pas conduire à des relations anormales. Aucune mise à jour signifie aucune anomalie; et pas de décomposition et aucune jointure. Vous pouvez tout pré-join.

En général, les données DW est décomposé selon un schéma en étoile. Cela vous guide pour décomposer les données dans les tableaux « faits » numériques qui contiennent les mesures - numéros avec des unités -. Et les références clés étrangères à la dimension

Une dimension (ou « entité commerciale ») est la meilleure pensée comme une chose du monde réel avec des attributs. Souvent, cela inclut des choses comme la géographie, le temps, produit, client, etc. Ces choses ont souvent des hiérarchies complexes. Les hiérarchies sont généralement arbitraires, définies par les différents besoins de reporting des entreprises, et non modélisés comme des tables séparées, mais simplement des colonnes dans la dimension utilisée pour l'agrégation.


Pour répondre à certaines de vos questions.

« cette adhésion doit être fait sur le côté de l'application des choses ». Genre de. Les données sont « pré-joints » avant d'être chargés. Les données de dimension est souvent une jointure de données sources pertinentes sur cette dimension. Il est rejoint et chargé en tant que structure relativement plate.

Il est pas mis à jour. Au lieu des mises à jour, sont insérés des documents historiques supplémentaires.

« mais ne pas commencer à coûter cher? ». Genre de. Il faut un certain soin d'obtenir les données chargées. Cependant, il n'y a pas beaucoup de rapports / analyse rejoint. Les données sont pré-joint.

Les questions ORM sont en grande partie sans objet puisque les données sont pré-joint. Votre ORM cartes au fait ou dimension, selon le cas. Sauf dans des cas particuliers, les dimensions ont tendance à être plutôt petite et tenir entièrement dans la mémoire. L'exception est quand vous êtes en Finance (Banque ou d'assurance) ou les services publics et ont des bases de données clients massives. Ces dimensions du client correspond rarement à la mémoire.

A JOIN est un terme relationnel pur et non toutes les bases de données relationnelles sont.

D'autres modèles de base de données ont d'autres façons de construire des relations.

bases de données de réseau utilisent les chaînes sans fin de find a key - fetch the reference - find a key qui doivent être programmées avec un langage de programmation commune.

Le code peut être exécuté sur le côté de l'application ou sur le côté serveur, mais il ne SQL et même pas basées sur des ensembles.

Si elle est conçue correctement, une base de données de réseau peut bу beaucoup plus rapide qu'un relationnel.

Par exemple, une base de données de réseau peut stocker une référence à une autre entité comme un pointeur direct à un décalage dans un fichier ou même un bloc sur un disque où les informations sur cette entité est stockée.

Cela fait traverser les réseaux supplémentaires rapidement -. Si vous avez écrit un code efficace pour faire

Une base de données relationnelle peut seulement stockent des références sous forme de paires de valeurs de base comme des nombres entiers (ou triples ou tuples d'ordre supérieur).

Pour trouver ces valeurs dans la base de données relationnelle, le moteur doit faire les choses suivantes:

  • En savoir où le tuple contenant la première valeur réside
  • Trouvez la deuxième valeur
  • Trouver l'adresse de la racine dans une B-Tree contenant les données du deuxième numéro fait référence à
  • Traverse cet arbre
  • Trouver le pointeur sur la table réelle (qui peut être stockée en tant que B-Tree lui-même, dans ce cas, le pointeur est la valeur de la PRIMARY KEY de la ligne que nous sommes après)
  • Trouvez par le pointeur ou parcourir la table de ligne de la table
  • Enfin, obtenir le résultat.

Et vous pouvez contrôler ce que dans une certaine mesure. Après que, vous émettez simplement la requête SQL et attendez.

Modèle relationnel fait pour simplifier la vie du développeur, de ne pas atteindre la vitesse super toujours et quoi qu'il arrive.

est le même que l'assemblage par rapport à des langues de niveau supérieur, modèle relationnel étant une langue de niveau supérieur.

Vous pouvez lire l'article dans mon blog

, où je tente d'expliquer les différences entre plusieurs modèles de base de données couramment utilisés.

Lorsque vous denormalise vos données de cette manière, vous le faites pour éviter les frais d'adhésion à des éléments disparates; vous acceptez que certaines données peuvent être reproduites et que certaines façons de combiner il peut être difficile, au profit de la performance de l'utilisation des requêtes simples.

Si vous avez à faire une grande quantité d'adhésion au niveau de l'application, elle implique que vous ne l'avez pas dénormalisé assez.

Idéalement, vous serez en mesure de faire une requête pour un ensemble de données que vous voulez. Dans la pratique, vous ne devriez pas avoir à utiliser plus de deux ou trois requêtes pour tous les aspects de votre application, et toute adhésion au niveau de l'application sera plus d'une récupération trivial de choses à partir des resultsets séparés pour l'insertion dans la vue.

Ce genre de chose n'est vraiment nécessaire pour les ensembles de données vraiment massive, et il y a toutes sortes de compromis impliqués. Pour donner un exemple: BigTable ne peut pas faire des requêtes globales, comme vous donnant un compte. Il peut être utilisé pour vous donner un chiffre qui est à peu près précis - dans le sens que si vous avez, disons, 12,149,173 dossiers dont 23721 ont été ajoutés dans la dernière heure, il n'a pas vraiment si le mieux que vous pouvez savoir est que vous avez « environ 12.100.000 dossiers ». Si votre application dépend de la connaissance du chiffre précis à un moment donné, alors vous ne devriez pas utiliser BigTable pour elle, est l'attitude générale.

Les applications comme Facebook ont ​​très peu de modifications de données, la plupart du temps les utilisateurs publient de nouveaux éléments.Ainsi, le fait que les enregistrements multipliés doivent être mis à jour lorsqu'un élément est modifié est un problème moindre.

Cela permet aux données de ne pas être normalisées sans frapper les problèmes courants avec les mises à jour.

Des applications comme Amazon peuvent se permettre de charger toutes les données d'un seul utilisateur dans la RAM (quelle est la taille d'un panier après tout ?), puis de mettre à jour les données dans la RAM et de les écrire comme un seul élément de données.

En supprimant à nouveau la nécessité de se normaliser la plupart des données.

Vous échangez l’évolutivité contre la facilité de développement d’applications. Par conséquent, si vous n’avez pas besoin d’évoluer vers de grandes hauteurs, vous souhaiterez peut-être conserver la facilité de développement d’applications offerte par les SGBDR.

Je pense que dans ces situations, vous allez être à peu près sur votre propre et allez devoir rouler tout vous-même. Je n'ai pas été là, mais ont jugé pour certains de nos projets. Vous pouvez obtenir assez grande avec BDs relationnelles (comme le montre l'SO), donc je continuerai à profiter de la bonté relationnelle pour l'instant.

En général, l'entreposage de données est construit autour de l'utilisation des jointures et des données divisées en dimensions et des tables de fait (avec soi-disant « schémas en étoile », etc.)

Jointures sera souvent pré-calculées et stockées sous forme de tableaux de-normalisés.

Je ne suis pas au courant des outils ORM qui fonctionnent avec des systèmes de bases de données qui ne permettent pas les jointures, car ceux-ci ne sont généralement pas considérés comme des bases de données relationnelles traditionnelles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top