Je travaille sur un projet de loisir appelé Gestion des menus / recettes.
Voilà à quoi ressemblent mes entités et leurs relations.
A Nutrient
a des propriétés Code
etValue
An Ingredient
possède une collection deNutrients
A Recipe
possède une collection de Ingredients
et peut parfois avoir une collection d'autresrecipes
A Meal
a une collection de Recipes
etIngredients
A Menu
possède une collection deMeals
Les relations peuvent être décrites comme
Dans l'une des pages, pour un menu sélectionné, je dois afficher les informations sur les nutriments efficaces calculées en fonction de ses constituants (repas, recettes, ingrédients et nutriments correspondants).
À partir de maintenant, j'utilise SQL Server pour stocker les données et je navigue dans la chaîne à partir de mon code C #, en commençant à chaque repas du menu, puis en agrégeant les valeurs nutritives.
Je pense que ce n'est pas un moyen efficace car ce calcul est fait à chaque fois que la page est demandée et les constituants changent de temps en temps.
Je pensais à un service d'arrière-plan qui maintient une table appelée MenuNutrients ( {MenuId, NutrientId, Value}
) et remplira / mettra à jour cette table avec les nutriments efficaces lorsque l'un des composants (repas, recette, ingrédient) change.
Je pense qu'un GraphDB serait bien adapté à cette exigence, mais mon exposition à NoSQL est limitée.
Je veux savoir quelles sont les solutions / approches alternatives à cette exigence d'affichage des nutriments d'un menu donné.
J'espère que ma description du scénario est claire.
Réponses:
En fonction des exigences et de l'architecture, il peut y avoir des options d'amélioration des performances:
Vous pouvez utiliser des vues indexées (matrialisées) pour améliorer les performances de lecture au niveau du SGBDR (serveur SQL).
Fondamentalement, tout ce que vous devez faire est de:
Créer une vue régulière.
Créez un index cluster sur cette vue .
L'utilisation d'un mécanisme d'encaissement au niveau de l'application améliorera les performances.
S'il est possible et faisable d'utiliser l'encaissement, avoir une stratégie de trésorerie comme l' encaissement paresseux singleton vous aidera.
NoSql:
Il y a beaucoup de bons articles sur Sql vs NoSql, comme ceci et cela
Les parties m'intéressent:
Où utiliser NoSql:
Lorsqu'il est utilisé, soyez prêt à:
En plus de décider d'utiliser ou de ne pas utiliser NoSQL, un article utile sur Comparaison SGBD NoSQL et l'intention d'entre eux pourraient être trouvés ici que certains d'entre eux sont concentrés sur haut Reads bas écrit, la carte-Reduce, HA ...
Avoir un regard au classement et à leur popularité , par catégorie peut être utile.
la source
En fait, vous n'avez pas besoin d'utiliser un graphe db, stockez simplement les valeurs requises dans un niveau supérieur. C'est comme stocker un
Order
etOrderItems
. vous n'avez pas à calculer le total chaque fois qu'une commande est sur le point d'être affichée. Au lieu de cela, vous calculez simplement la somme, la TVA et d'autres choses et les stockez avec votreOrder
.la source
Je suggère de regarder le modèle de séparation de la responsabilité des requêtes de commande .
Fondamentalement, au lieu de créer un seul modèle pour lire et écrire, vous pouvez créer 2 modèles différents. L'un optimisé pour la mise à jour et l'autre optimisé pour les requêtes (lecture, reporting, ...). Les 2 modèles sont synchronisés (généralement avec une cohérence éventuelle) à l'aide des événements de domaine (voir DDD).
J'ai commencé à étudier ce modèle il y a quelques mois et cela a vraiment changé ma façon de modéliser les logiciels. Ce n'est pas facile car c'est un grand changement, surtout lorsqu'il est utilisé avec d'autres techniques comme DDD et Event Sourcing. Mais ça vaut le coup.
Il existe de nombreuses ressources disponibles sur le net, recherchez CQRS et DDD (et éventuellement Event Sourcing).
Ce modèle peut être utilisé à la fois sur SQL et sur noSql.
Dans votre cas, vous pouvez déclencher un événement chaque fois que les nutriments sont modifiés pour mettre à jour le modèle de lecture optimisé pour la lecture. Le modèle de lecture peut être par exemple une vue dénormalisée des nutriments du menu (pourquoi ne pas utiliser une base de données nosql pour une lecture efficace). Vous pouvez avoir plusieurs modèles de lecture en fonction des requêtes que vous devez effectuer.
Il y a quelques implications en utilisant cette approche mais elle est très évolutive et extensible.
la source
Cela dépend grandement de la façon dont vous obtenez les menus et les nutriments au départ. Pourquoi pensez-vous que ce ne sera pas efficace?
D'après ce que je comprends, vous allez à la base de données, obtenez le menu, puis recommencez, récupérez chaque recette, puis recommencez et récupérez chaque ingrédient, etc. C'est vraiment inefficace, car il y a beaucoup de requêtes et d'aller-retour vers le serveur, qui est la principale source de retards. Ceci est connu comme le problème SELECT N + 1.
Ce que vous devez faire est de récupérer toutes les données dans une seule requête, en utilisant
JOIN
s pour toutes les tables du menu jusqu'aux nutriments, afin que le serveur de base de données puisse utiliser toutes les relations et les index pour obtenir les données en une seule fois. L'application cliente C # traite et affiche uniquement le résultat final. Cela est beaucoup plus efficace que d'aller un par un.En général, en utilisant les techniques de requête appropriées et les bons index pour les requêtes critiques, les bases de données relationnelles peuvent très bien fonctionner sur de grandes tables sous charge.
la source
JOIN
s qui ne devraient pas être une charge pour le serveur (sauf si nous parlons de récupérer des centaines ou des milliers de lignes), si l'indexation appropriée est en place. Même avec des ensembles de données volumineux, vous pouvez toujours créer une vue sur l'ensemble du résultat, et même indexer la vue pour que le résultat soit précalculé, si les performances deviennent un problème.Il semble que vous ayez passé du temps à réfléchir à la meilleure façon de modéliser les données afin qu'elles puissent être facilement mises à jour et interrogées. Cependant, vous êtes maintenant au point où vous devez donner accès aux données. Ces deux choses sont des préoccupations distinctes.
Vous mentionnez que le rechargement de la page provoque une nouvelle requête dans la base de données. Vous mentionnez également que la base de données sera mise à jour de temps en temps et lorsque vous souhaitez que ces mises à jour soient affichées sur la page en temps opportun. Votre meilleure méthode pour réduire les frais généraux des requêtes est de ne pas les faire. Si vous exécutez les mêmes requêtes encore et encore et obtenez les mêmes résultats, pourquoi ne pas les mettre en cache pendant un certain temps? Vous devriez pouvoir implémenter une certaine mise en cache en amont sans modifier le reste du projet. Je recommanderais de lire sur le repos. Peu importe si vous implémentez le projet dans un rdbms ou nosql, les problèmes de performances de ce type sont mieux traités en réduisant le nombre de fois où vous devez vous rendre dans la base de données. Supposons que vous ayez 100 demandes pour la même recette en 60 secondes. Si vous mettez en cache pendant 60 secondes, vous n'appuyez sur la base de données qu'une seule fois, ce qui représente une amélioration de 100 fois les performances. Pour voir ce même niveau d'amélioration en passant à nosql, il faudra beaucoup plus de travail.
Les systèmes de type Nosql peuvent être une excellente solution lorsque vous avez d'énormes quantités de données ou des exigences de vitesse de lecture ou d'écriture extrêmes. Cependant, cette performance supplémentaire a un coût de rejet de choses comme l'intégrité référentielle.
la source
Il semble que dans le cadre de l'expérience ou de la connaissance, vous souhaitiez essayer Graph-DB, mais votre exemple est clairement un exemple de données hiérarchiques où nous pouvons effectuer une exploration / montée à travers un nœud. Je ne suis pas expert en Graph / Neo DB mais je peux voir qu'il n'y a pas beaucoup de complexité dans la façon dont l'utilisateur / vous pouvez demander des données à partir de ce schéma. Je vois que le choix de la conception de la base de données / du schéma dépend beaucoup de la manière et du type de données qui seront interrogés. Comme vous utilisez SQLSERVER "HierarchyI" D est la meilleure option de mon point de vue pour placer ces nœuds dans le cadre de l'arborescence.
la source
Ma suggestion est de penser comme une machine et non comme un humain. Cela peut sembler répétitif, mais c'est à cela que les machines sont bonnes. Une chose que vous devez vous demander est "dois-je récupérer chaque objet, de toute façon, pour l'afficher sur ma page?" Si oui, continuez ce que vous faites, par rapport à la récupération de données, les cycles de processeur sont négligeables lorsque vous faites des calculs simples.
la source