MongoDB est-il le bon choix dans mon cas? [fermé]


9

Je vais construire mon premier vrai projet dans Rails qui consiste en une application web composée de 3 parties principales:

  • La partie statique où aucune base de données n'est utilisée
  • La partie Enregistrement d'utilisateur qui nécessitera une base de données et je peux utiliser MySQL car la ligne de chaque utilisateur aura les mêmes champs
  • L '"App" où les utilisateurs pourront créer, organiser, éditer ... des éléments dans des collections et les partager avec d'autres utilisateurs

Il y aura plusieurs types d'élément et chacun aura différentes options, par exemple je peux avoir des éléments "vidéo" avec les options suivantes:

  • id
  • identifiant d'utilisateur
  • collection_id
  • Titre
  • plate-forme (si intégrée)
  • url (si incorporé)
  • nom de fichier (si hébergé sur mon application)
  • taille du fichier (id hébergé sur mon application)

et "éléments de la carte":

  • id
  • identifiant d'utilisateur
  • collection_id
  • Titre
  • plate-forme (google maps, bing maps ...)
  • emplacement
  • url
  • taille de la carte

Comme vous pouvez le faire pour les utilisateurs, je peux utiliser MySQL pour les éléments, la flexibilité de MongoDB peut être utile car chaque élément peut avoir besoin d'options différentes puis d'un autre

Jusqu'à présent, j'ai toujours utilisé PHP et MySQL (toujours sur l'hébergement partagé pour les petits projets) et l'évolutivité est un mot totalement nouveau pour moi.

J'ai le temps d'apprendre mais j'aimerais pouvoir faire quelque chose de concret en quelque chose comme 1 mois.

J'ai beaucoup lu sur MongoDB et NoSQL vs RDMS et MySQL et après l'avoir essayé, je dois dire que j'aime le fonctionnement de MongoDB: pas de tables, pas de lignes et ses documents JSON comme ça:

  • Dans ma situation, que recommanderiez-vous? Pourquoi?
  • À propos de l'évolutivité, il peut y avoir des problèmes avec MongoDB? si oui quand (en termes de taille de base de données) et ces problèmes peuvent-ils ralentir considérablement mon application?

Modifier: comment l'application fonctionnera

Étant donné que beaucoup ont demandé, voici comment j'aimerais que l'application fonctionne:

  1. Un utilisateur s'inscrit
  2. Il est connecté
  3. Il crée sa première collection à partir de laquelle il peut créer des objets infinis
  4. Les éléments sont de différents types et chaque type nécessite des données différentes pour être enregistré dans la base de données et le type d'éléments peut être ajouté ou modifié

Les utilisateurs peuvent créer d'autres collections et éléments à l'intérieur.

Nous avons donc CRUD pour les collections et les articles à l'intérieur d'eux et chaque collection / article est référé à un utilisateur spécifique

Le principal problème avec MySQL est qu'il n'a pas de schéma flexible, il existe un moyen de résoudre ce problème (une solution de contournement?)?

En pensant à NoSQL, le seul doute que j'ai est sur la jointure, par exemple, étant donné une certaine collection, je veux récupérer les données liées au champ User with id = user_id dans la collection

EDIT: idée de continuer à utiliser MySQL

Créez un champ dans le tableau "articles" avec des paramètres facultatifs, chaque paramètre étant divisé par un | ou un autre symbole.

Ensuite, je vais enregistrer quelque part la structure de chaque élément des paramètres facultatifs, par exemple le type d'élément "notes" nécessite deux paramètres facultatifs "couleur" et "étrange_setting", lorsque j'obtiendrai les données de MySQL, je diviserai le champ des paramètres facultatifs en un tableau sachant que le premier élément du tableau est pour "couleur" et ainsi de suite.

Qu'est-ce que tu penses? il y a un problème avec cette solution? avez-vous d'autres idées?


4
Les questions de Matteo sur les recommandations technologiques sont hors sujet, sauf si vous nous présentez un problème spécifique que vous essayez de résoudre. Vous devrez nous donner un peu plus d'informations sur votre projet et sur les raisons pour lesquelles vous pensez que vous devez utiliser une autre base de données que MySQL (qui est celle que vous connaissez). Par exemple: Existe-t-il des problèmes d'évolutivité et de combien de temps disposez-vous pour étudier les nouvelles technologies? Envisagez de réviser votre question et si vous le faites, signalez-la pour une attention modérée afin que nous puissions examiner vos modifications.
yannis

Réponses:


10

Nous ne pourrons peut-être pas vous aider tant que vous ne nous aurez pas dit ce que vous avez l'intention de faire avec l'application. Les bases de données relationnelles sont bonnes pour certaines choses, et les bases de données NoSQL sont bonnes pour d'autres.

Comme quelqu'un me l'a dit un jour sur SO:

la partie relationnelle d'une base de données relationnelle est bien plus optimisée que certaines autres parties

Cela signifie que vous pouvez également utiliser une base de données relationnelle si cela semble correspondre à vos cas d'utilisation. Ne vous contentez pas d'aller de l'avant avec MongoDB en raison de sa flexibilité / évolutivité. Ceci est la première ligne sur MongoDB sur Wikipedia:

MongoDB (de "humongous") est un système de base de données NoSQL orienté document open source.

Avez-vous vraiment l'intention d'utiliser une base de données orientée document? S'il y a du graphisme dans vos cas d'utilisation, alors vous pouvez très bien opter pour une base de données graphique comme Neo4j. Ou vous pouvez très bien utiliser le meilleur de SQL et de NoSQL ensemble comme certaines personnes le font.

BTW, je fais aussi un projet dans lequel j'utilise les meilleures parties de SQL et de NoSQL.

EDIT: Je dis encore une fois:

Consultez la section Neo4j vs Hadoop de cet article. Ça dit:

En principe, Hadoop et d'autres magasins de valeurs-clés sont principalement concernés par des structures de données relativement plates . Autrement dit, ils sont extrêmement rapides et évolutifs en ce qui concerne la récupération d'objets simples, comme des valeurs, des documents ou même des objets.

En vous référant au même article, avez-vous vraiment besoin d'une structure de données plate pour laquelle vous optez pour MongoDB? Cela dépend finalement de vos cas d'utilisation détaillés, de la façon dont les étapes 3 et 4 vont être effectuées.

En outre, vous souhaiterez peut-être renvoyer ces questions:

/programming/2124274/mongodb-what-to-know-before-using

/programming/1476295/when-to-use-mongodb-or-other-document-oriented-database-systems

( Vérifiez la réponse supérieure / sélectionnée de la deuxième question à coup sûr. Vous êtes dans ce dilemme que cela pourrait résoudre. )

Je suppose que ces questions contiennent toutes les informations que vous vouliez savoir. En fin de compte, c'est vous qui devrez décider si c'est MongoDb ou autre chose, nous pouvons simplement recommander. Les seules personnes qui connaissent vos cas d'utilisation détaillés sont vous et votre équipe.

MODIFIER ENCORE (pour la partie MySQL): Si je comprends bien, vous prévoyez de stocker quelque chose dans la base de données et de les séparer via un séparateur. Cela présente 2 problèmes:

  1. Vous devez en outre gérer toute entrée qui aura le séparateur.
  2. La partie de stockage relationnel d'une base de données relationnelle est bien plus optimisée que la partie de correspondance de chaîne. Je n'irais pas pour un schéma où je dois faire une correspondance de chaîne dans une base de données pour obtenir un résultat spécifique. Encore une fois, je souligne:

    la partie relationnelle d'une base de données relationnelle est bien plus optimisée que certaines autres parties (par exemple la correspondance de chaînes)

  3. N'utilisez pas d'attributs à valeurs multiples. Les gens les redoutent généralement.

principalement j'allais utiliser MongoDB pour son schéma flexible mais j'ai quelques doutes car il n'a pas de jointure. Quoi qu'il en soit dans mon application, j'aurai une base de données pour les utilisateurs, puis un creud de base où chaque élément est associé à un utilisateur et une collection d'éléments
Matteo Pagliazzi

Vous n'aurez pas besoin de rejoindre pour mongo mais vous devrez planifier votre schéma. Pensez en termes d'objets plutôt que de tables si vous utilisez mongo. Réfléchissez ensuite à la manière dont vous allez accéder à vos objets.
ltfishie

8

Je vois beaucoup cette question. Il semble toujours être considéré comme l'un ou l'autre. MongoDB est un excellent nouvel outil. C'est aussi parfois comme l'outil brillant pour tout et cela peut être un mauvais choix dans mon expérience.

Je pense que la meilleure combinaison est définitivement LES DEUX et je voudrais vous féliciter pour votre approche de l'utilisation de mylsql pour certaines parties, telles que les utilisateurs, mais utilisez MongoDB pour d'autres parties car je pense que l'authentification et l'autorisation sont mieux effectuées avec mySQL et il y a une tonne d'exemples et de modules qui le font très bien.

Pour la pièce `` grand nombre d'éléments '', c'est là que vous voudrez envisager d'utiliser mongoDB si votre volume est élevé, et / ou il s'agit principalement de lectures et / ou de données non structurées.

Je conseillerais de ne pas baser votre décision sur la flexibilité sans schéma de Mongo. SQL et les schémas sql sont nés d'un besoin d'avoir des données structurées et de pouvoir effectuer des calculs et des transformations qui ne sont possibles qu'avec une telle structure. Je l'ai appris de 5 ans de travail dans un rôle d'entrepôt de données. Je ne regarderais que MongoBD pour le problème de performances. Si vous êtes ou attendez un volume élevé d'utilisateurs et de demandes, disons 100 000 utilisateurs et 20 demandes par seconde, j'utiliserais mongoDB, sinon j'essaierais de rester avec sql. Dans de nombreux cas, j'utiliserais mySQL pour un faible volume, puis, comme le volume, les revenus et l'infrastructure le soutiennent, je passerais à Oracle, avant de mixer dans mongoDB. Je suis d'accord que vous ne devriez pas essayer de traiter les problèmes de volume avant de les rencontrer, cependant si vous avez une idée juste de la direction que vous prenez et que vous ne le faites pas. t vouloir réécrire les choses à mi-chemin, il est très judicieux de choisir les bonnes technologies dès le départ. N'oubliez pas que si vous avez vraiment ce volume élevé, il y aura une énorme quantité d'options et de technologies à tous les niveaux de la pile que vous chercherez à utiliser.

Il y a des inconvénients aux données peu structurées. J'utilise l'analogie du parking ici. aucune ligne de démarcation n'est idéale pour les 3 premières voitures qui entrent, mais à mesure que de plus en plus de voitures entrent, beaucoup de désorganisations commencent à se produire et essayer de se garer ou de compter facilement les voitures et de garder les voies libres devient un cauchemar. Organiser cela demande du travail à l'avance - délimiter les lignes et les séparations et les flux de trafic, etc., mais cela porte ses fruits. Parfois, les choses changent bien sûr (les voitures grossissent) et vous devez faire quelques changements - repeindre les lignes. Plus juste un temps d'arrêt standard pour les repeints et l'entretien annuels.

L'aspect de conception de schéma sera probablement le plus grand obstacle pour les utilisateurs traditionnels de mysql. Je pense que la page MongoDb sur la conception de schéma aide à cela. Mon dernier point est que chaque technologie que vous ajoutez au mélange ajoute de la complexité. Il y a souvent d'énormes défenseurs d'une pièce donnée qui diront que vous "devez" l'utiliser, mais j'ai trouvé qu'un facteur vraiment important est le nombre de pièces. Cela implique plus de points d'échec possibles et surtout plus d'une base de connaissances nécessaire pour que quelqu'un d'autre doive savoir pour travailler dessus.

fyi Rick Obsorne a un diagramme de comparaison assez étonnant qui est tout à fait unique!


c'est mon premier vrai projet sur les rails: c'est un hobby et pour l'instant je ne sais pas si ça va être un succès ou un échec mon premier objectif ici est de me faire connaitre avec les rails donc je ne peux pas parler de trafic. Les lectures ne seront pas primaires, j'aurai aussi beaucoup de nouvelles données et une mise à jour ...
Matteo Pagliazzi

1
une bonne chose à propos de mongodb est qu'il n'y a pas de schéma fixe, donc pour un projet de loisir, il y a moins de travail de configuration. Le schéma peut évoluer au fil du temps et vous n'avez pas à effectuer l'étape supplémentaire de mise à jour des tables SQL.
Kevin

pas sûr de mon -1 ou pourquoi 0 mauvais conseil ou en désaccord?
Michael Durrant

Quoi qu'il en soit, si c'est votre premier projet sur les rails, je m'en tiendrai à mySQL. Il y a BEAUCOUP à apprendre dans les rails, qui valent bien plus d'un mois une fois que vous commencez à tirer les rideaux.
Michael Durrant

@michael voir ma dernière mise à jour
Matteo Pagliazzi

3

Je vois beaucoup d'arguments valides ici pour NoSQL vs MySQL. Un lien manquant est cependant sur l'échelle: si vous voulez vraiment évoluer et le faire avec une base de données interne, vous aurez besoin de BEAUCOUP de connaissances sur les bases de données. Il y a trop d'histoires d'horreur là-bas où les gens n'ont pas réussi à mettre en œuvre un système qui évoluera à l'infini.

Si vous choisissez vraiment d'opter pour la route NoSQL (et êtes prêt à prendre les coûts qui en découlent - comme aucune jointure), pensez à AWS DynamoDB (http://aws.amazon.com/dynamodb/). Ici, vous pouvez oublier toute la partie mise à l'échelle de la base de données et vous concentrer sur votre application. Bonne chance.

Avertissement: je suis développeur au sein de l'équipe AWS DynamoDB, mais je crois vraiment en notre produit. Essayez-le :)


1

Ainsi, votre conception peut enregistrer dans votre base de données deux types d'objets différents:

  • Objet utilisateur (qui a toujours les champs).
  • Objets Apps (qui peuvent avoir différents champs). Une application n'appartiendra qu'à un seul utilisateur.

Une collection pourrait ou non être créée en tant qu'objet différent, tout comme une balise pour regrouper différentes applications. Par souci d'argument, disons qu'il n'y a pas de collections et que les utilisateurs n'ont qu'une liste d'applications.

Bien que je pense que cela soit réalisable sur MySQL, dans MongoDB, vous aurez une plus grande flexibilité en termes de structure des objets de l'application, et probablement cela mappera plus naturellement votre représentation dans la base de données, ce qui rend le code plus simple.

Dans MySQL, vous aurez des problèmes avec différents formats pour différentes applications, mais c'est possible. Quelques idées:

  • Vous pouvez créer une table intermédiaire avec toutes les informations communes entre tous les objets (id, id_utilisateur, titre, etc.), puis le type, afin que vous puissiez la rechercher sur une autre table avec uniquement les champs non communs pour ce format (par exemple nom_fichier et taille_fichier pour les fichiers). Vous devrez créer un tableau différent pour chaque format différent. Si les deux tables sont indexées par app_id (clé primaire), ce sera assez rapide, car l'accès à une table par une valeur indexée est rapide.
  • Vous pouvez encoder les données dans un certain format et les stocker de manière standardisée. Par exemple, encodez les données non communes en JSON sous forme de chaîne et stockez-les dans un champ VARCHAR. Soyez prudent avec la taille de ce champ afin de ne pas manquer d'espace. Le format peut être complexe (JSON) ou simple (juste des valeurs séparées par des virgules)
  • Vous pouvez créer différents champs "génériques", quelque chose comme int1, int2, str1, str2 et définir que str1 pour un type d'application est "nom_fichier" tandis que pour un type différent pourrait être "emplacement".

Sur MongoDB, cela pourrait être aussi simple que d'utiliser simplement deux collections MongoDB, une pour les utilisateurs et une autre pour les applications. En supposant une sorte de limite (ce qui n'est pas le cas, comme vous l'avez décrit, mais juste pour le dire), vous pouvez même stocker les applications à l'intérieur de l'objet utilisateur, sous forme de liste. Le stockage et la récupération des données sont plus naturels, car vous pouvez stocker n'importe quel type d'objet, quels que soient les champs. Vous pouvez rechercher par user_id pour obtenir toutes les applications qui appartiennent à un utilisateur. Sur MongoDB, vous perdez de toute façon la possibilité de faire des requêtes de jointure, mais dans ce cas, je pense que les requêtes de base permettront de récupérer l'utilisateur et de récupérer les applications liées à l'utilisateur. Si vous prévoyez de faire beaucoup de choses comme "donnez-moi les utilisateurs qui ont plus de deux collections avec trois applications ou moins sur chacune", vous devrez le générer non pas comme une requête de jointure, mais en tant que processus dans le code, et sera moins naturel que dans une base de données relationnelle et peut prendre plus de temps à traiter. Si vous souhaitez rechercher des paramètres (par exemple, donnez-moi toutes les applications qui appartiennent à un utilisateur particulier; donnez-moi toutes les applications de type X), c'est assez facile sur MongoDB et vous n'avez pas besoin d'utiliser de jointures.

Je ne suis pas sûr du support de MongoDB on Rails. Je l'ai utilisé en Python et JavaScript.

EDIT: Ajout d'un commentaire sur le temps lors de l'accès à deux tables et à une autre option MySQL


Je n'aime pas la deuxième option pour utiliser MySQL pour stocker des paramètres facultatifs car je pense qu'elle peut charger chaque ligne avec beaucoup d'octets non nécessaires ... pour la seconde: cela ralentira beaucoup mon application pour charger deux lignes à partir de deux tables différentes pour charger un élément?
Matteo Pagliazzi

s'il vous plaît voir ma dernière mise à jour
Matteo Pagliazzi

À propos de votre question sur la vitesse, elle ne devrait pas être beaucoup plus lente (vous y accédez via une valeur unique indexée). J'ai également modifié ma réponse, car la dernière proposition modifiée est similaire à la première idée et j'ai ajouté une autre option.
Khelben

1

Je dirais utiliser la technologie que vous connaissez le mieux, surtout si c'est un vrai projet et que vous voulez le faire sortir rapidement. L'utilisation de MySQL et de Mongo aura ses propres avantages et maux de tête. Ayant travaillé avec les deux, j'ajouterais également qu'il n'est pas très difficile de migrer de MySQL vers Mongo si vous suivez de bons principes de conception.

Cela dit, une bonne raison d'utiliser MongoDB dans votre cas est vos données. Comme vous l'avez mentionné, vous aurez plusieurs types d'entrées pour vos collections: carte, vidéo, etc. Si vous deviez l'implémenter à l'aide du SGBDR, vous avez 3 approches:

  • table par type: chaque table contient des colonnes spécifiques à chaque type d'objets

    Inconvénients : requête N pour rechercher dans tous les types de données.

    Avantages : bonne conception OO, facile à entretenir

  • table unique: une immense table contenant tous les attributs possibles pour tous les types, la plupart d'entre eux étant nuls pour une entrée particulière

    Inconvénients : Le changement de n'importe quel objet nécessitera un changement de table, douloureux une fois que la table devient grande. Difficile à entretenir.

    Avantages : Facile à mettre en œuvre.

  • table de base avec métadonnées: vous avez une seule table avec les attributs de base, par exemple le titre, les dates et une table de métadonnées avec des paires clé-valeur pour des attributs supplémentaires

    Inconvénients : Deux requêtes pour obtenir toutes les données d'un seul objet.

    Avantages : Extrêmement flexible, pas très difficile à mettre en œuvre.

J'ai déjà utilisé chacune de ces approches, et je peux dire qu'aucune n'est aussi naturelle de travailler avec Mongo. Vos données ressembleront probablement à ceci:

{_id:"collection1",
 name:"My first Collection",
 owner: "user123243342",
 entries: [
    {type:"video",
     url: "http://www.youtube.com/234324",
     tags: ["roadtrip", "fun", "camera"]
     },
    {type:"map",
     coordinates: [LOC: [38, –102], LOC: [43, –33], LOC: [228, –102]],
     description: "Road trip to nowhere",
 ]
}

Mais vous n'aurez pas vraiment à vous soucier de la conception du schéma, car vos objets de domaine peuvent être directement conservés en tant que tels. MongoDB est essentiellement votre magasin d'objets sur lequel vous pouvez interroger.

J'ai remarqué que j'ai laissé de côté toute discussion sur la comparaison des performances entre MySql et Mongodb. Bien que vous deviez toujours garder à l'esprit les performances, vous ne pourrez pas prendre de décision efficace à moins de connaître le modèle d'accès aux données. Tout bon projet passera probablement par quelques itérations de refactorisation à mesure qu'il grandit et que de nouveaux défis émergent. Ne vous inquiétez pas des performances prématurément et choisissez l'outil que vous connaissez le mieux et commencez à coder.

Éditer

Pour répondre à votre question spécifique sur l'utilisation de MySQL et la conservation des attributs dans le même champ en utilisant "|". Ne fais pas ça. Cette approche vous donnera plus de problèmes qu'elle n'en résout. Tout d'abord, vous ne pourrez pas interroger des attributs individuels à l'aide de MySql. Deuxièmement, cela ajoute trop de complexité à votre couche d'accès aux données. Utilisez plutôt le type par table ou l'approche des métadonnées. Si vous avez travaillé avec WordPress auparavant, il utilise l'approche des métadonnées:

  • table utilisateur + usemeta pour l'utilisateur
  • poteau de table + poteau de table postmeta

Cela rend la structure de données extrêmement flexible et toujours interrogeable à une vitesse raisonnable.


je n'aime pas l'option de métadonnées ... mais je pense à la table unique avec des champs laissés nuls s'ils ne sont pas utilisés
Matteo Pagliazzi

L'approche à table unique est probablement la pire du lot. Bien que vous puissiez tout faire dans une seule requête, toute modification d'un type de données unique nécessitera une modification de la table. Et c'est une douleur dans mysql une fois que votre table devient grande.
ltfishie

0

L'article ci-dessous fournit de bons résultats comparant MySQL et MongoDB en termes de sélection, d'extraction et d'insertion, compte tenu de la quantité de données dans la base de données et de la quantité de données récupérées. Les résultats montrent une grande performance pour MongoDB en ce qui concerne les "insertions", mais les autres cas MySQL gagne. Voir ci-dessous:

http://www.moredevs.ro/mysql-vs-mongodb-performance-benchmark/

J'ai eu une expérience en utilisant MongoDB que je pense que c'était une bonne solution. Je l'ai utilisé pour insérer des milliers de collections chaque jour. Combiné avec la solution Solr (solution de cache, mise à jour une fois par jour), je peux récupérer les données MongoDB par l'ID de collecte en cas de besoin, donc je n'ai pas besoin de sélections à la volée. Donc, compte tenu du fait que vous devez gérer de nombreuses insertions et que vous n'avez pas besoin de vous soucier de la sélection et de la récupération, MongoDB pourrait être une excellente idée, cela dépendra de chaque cas et fera une bonne analyse.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.