Pergunta

I have a web app which has users, forms, and volunteers signed up on those forms.

Currently I am using MongoDB and have it setup with a collection for admins, and a collection for forms with volunteers attached to the forms.

It is not very efficient because I have to render the forms on two pages, so I have form data attached to admins in the user collection, but repeated in the form collection so they can be rendered individually on the form page.

Currently I have one page which needs to render admins and forms, and then the form page which just renders a single form. I am trying to minimize queries, which is why I copied form data to the user objects (admin info is also attached to the form, keeping it to one query for each page).

Volunteer information is attached to the forms, so it is copied in both collections. Obviously this is a terrible waste of space. I'm hoping someone can help me re-design this and recommend whether to stick with NoSQL or move to MySQL/Postgres.

I do not have enough experience to know which is better for this specific setup, or how to set the schemas/architecture to be scalable.

Thank you very much for your time. Any advice is appreciated, including relevant resources that I clearly do not know about.

Foi útil?

Solução

Based on the data you provided I would say this could be made to work both ways.

However, since you started off with MongoDB, I will highlight that:

First of all, I think you are starting off on the wrong premise: you are trying to cut down on the reads to the database. But MongoDB is designed for fast access to large amounts of data, that's why and when you would use it.

If you were talking about trying to reduce 40 reads to 5 reads that would be one thing. But from what I can tell you are cutting down 2 reads to 1 read. If your MongoDB cannot handle 2 reads per user request, you are doing something wrong. Review your indexes.

And if you actually get too much traffic, you can always add another server to the replica set or shard the collections.

So, I would simply store the admins in one collections and the forms in another. Duplicating data is never good and with the non-transactional nature of MongoDB you are liable to run into them not matching up in some cases.

In order to efficiently be able to cross reference both of these collections, you could set-up your schema like this:

Admins

{
   "_id" : 12345
   "name" : "Joe"
   "formIds" : [
      1234,
      5678
      9123
   ]
}

Forms

{
   "_id" : 1234,
   "field1" : "bla",
   "field2" : "bla"
   "adminId" : 12345
}

This way you can create indexes and lookup the admin by the formId and the form by the adminId. You could also only use one of the methods of cross reference - whichever suits your access patterns better.

Note: Now, we wound up basically with a relational database schema, just executed in MongoDB. And thus it won't make a big difference.

So where MongoDB would come in handy is, if you have forms, that have variable fields or change over time or forms that have nested data, all of which would require a complex schema on MySQL.

Outras dicas

We can't answer that. It depends on more than just your schema or lack thereof. It depends also on how you hit the service (in code), how your users hit the application, what sort of caching you're prepared to implement, etc.

Use the storage mechanism that is more well suited to how you think and code. Keep interactions with that storage service as isolated and abstracted away as is reasonable for you to do. And if performance becomes a problem, hire a DBA and/or more fully abstract the service so as to compare options with a representative workload.

Licenciado em: CC-BY-SA com atribuição
scroll top