Database design - Refs or embedded docs for this project?

I recently joined FCC, seems like a great community, glad to finally have joined.

Alright, I’m trying to design the database for a project but I’m a bit stuck on whether to use references or subdocuments (embedded docs).

Technologies:
Node.js, express, Mongoose.

Project Overview:
Similar to a todo list application but a bit different.

  • A user needs to sign up/sign in to use the app.
  • Each user has a list of todos (with more properties than just a ‘task’)
  • Each todo has a list of subtodos (with many properties)

Design Question
Docs as references refers to a separate collection whereas an embedded doc only has it’s own schema but no collection. I’d think that it would make more sense to have only 1 collection in the db (the users collection) and then have a todoSchema and a subtodoSchema.

  • e.g.
const subtodoSchema = new mongoose.Schema({
    /* some fields  */
});

const todoSchema = new mongoose.Schema({
    subtodos: [{
        type: subtodoSchema
    }]

    /* other fields  */
});

const userSchema = new mongoose.Schema({
    todos: [{
        type: todoSchema
    }]

    /* other fields  */
});

const User = mongoose.model('User', userSchema);

OR, is it better to have a users collection AND a todos collection? And the reference the todos collection within the users collection, and have the subtodoSchema embedded as a subdoc in the todos collection. But since all the todos only make sense within the context of a user, I would think that I should only have a single collection (users).

I’d really appreciate some feedback!! (since refs and embedded docs have pros and cons for querying purposes and consistency, I’d happily welcome some suggestions there as well).

:slight_smile:

Basically this is about simplicity and backup IMHO.

Storing docs in database
Simpler and faster, but the database grows fast and backup will slowdown.

Storing docs outside database
Harder but safer and backup can be done incrementally. And restoring documents may be simpler.

This is a debate that occurs now and then and there are different opinions…

Okay thanks for the feedback!

So let’s say I have:

users collection
— todo embedded subdocs
-------- subtodo embedded subdocs

If a user needs to update a subtodo would the API endpoint look something like this:

app.put('/api/users/:id/todos/:todo_id/subtodos/:subtodo_id', (req, res) => {
    /* handle request */
});

Or am I completely wrong in thinking this…?

Another approach is to add a “level” column and store the documents flat. But my experience is from Postgresql, so this may not apply on Mongo.

Yeah, we don’t use columns in noSQL dbs. But I’ll try to figure it out, maybe more people will add to this conversation too. Thanks anyway!!

Don’t you use “tags” (= basically json columns)?

{
"_id" : 1,
"name" : { "MongoDB"},
"customers" : [ "Metlife", "OTTO", "Expedia", "ADP" ],
"applications" : [
{ "name" : "Forward",
"domain" : "e-commerce"
},
{ "name" : "Calipso",
"domain" : "content management"
}
]
}

As a SQL guy, i should think of using this ids and create relational behavior using Javascript. Documents separated from the todos. But I guess this is a newbie way of thinking.

Yeah we can create a kind of relation to another document either by using references or embedded subdocuments, but again, I’m not sure which one is the right one for this type of project. Since it’s not a social app where users should be able to see the todos of other users I was thinking it’s better to go with just embedded subdocs (shown in the original example).

But yeah, I could technically use both but I just want to the most appropriate one :stuck_out_tongue:

Hello people of FCC! Would love if I could get some more feedback to my initial question…? much appreciated :slight_smile: