So in the last lecture we had a look at a many-to-many relationship where changing data might not be
that bad for our duplicates and therefore embedding the documents might be fine.
Now let's have a look at a many-to-many relationship where splitting it up and using references might
be better.
Here we got a couple of books and a couple of authors and one book can be written by multiple authors
and one author will probably write more than one book,
so it's a typical many-to-many relationship,
now let's see how we could model that and how we could store that in our database.
Let's create our book registry database here and in there, I'll have my books collection and I'll insert
a new book with a name,
my favorite book and with some authors and here let's first of all go for the embedded approach.
So I'll have an author, Max Schwarz, age 29
and I'll have another author, name is Manuel Lor, age 30,
if I hit enter, we can of course find all our books here, pretty print them and see we got embedded author
documents.
Now we'll also have our authors collection typically because when we're managing books and authors, well
we'll need both kinds of data and authors might then be a collection where we insertMany authors with
square brackets as you learned, then multiple documents separated by commas and
there we might have name Max Schwarz, maybe that also is our unique identifier we can use,
otherwise we should also store an ID here in the authors of the book.
But here we got that, we also got the age
and there let's say we also have the address as an extra field with a street and so on. Now we get the
second author which is Manuel Lor, age 30
and there we also got an address with a street,
like this.
I can look into my authors of course with find and pretty print that
and I see my author data.
Now that would be a typical use case,
we got our books with embedded author data and that could be all or some of the data we have in the authors
collection and we get just the authors collection,
the problem is if one author changes, maybe I got older, maybe I moved, then I need to update that everywhere
where I use that and that's not just the authors collection but that would be all my books and that is
especially important let's say if I changed my name because I married, then I can't say now I don't care
it's an old snapshot like we did for the orders. For the books and for the authors, I want to have the most recent
data of course
and if I'm displaying the age in the book, I might say that is a snapshot data, that is ok, for the name
it's probably not and in my registry in the database even the age is not ok,
that should be all up-to-date for future books, for future prints, let's say.
So here, if we then change the name of the author, we have to change it here with the update method in
the authors collection
and we also have to change it in the books collection by finding all books where this author is an author
and that is a lot of work and a lot of write and update requests. This is bad from a performance perspective
because we have to well write a lot to the database,
it also is error prone because we might be overlooking some document
we should update
and therefore, this is probably not the best approach for this scenario because in our application, if
the data does change, it should change everywhere.
Now even with that, it might be ok if changes are very unlikely to happen
but some data like the age will change at least once a year, other data might change more frequently and
the more frequent we can expect such changes,
the more often we'll have to touch dozens or one hundreds of documents, so the worse the matter gets. So low
frequency might still let us get away with this approach and might make it a good approach, with higher
frequency,
it almost most certainly is not a good way of relating this.
So instead of using embedded documents here, we should go for the reference approach, so we should take
the references of our authors and then go to our books collection, update the book in our case here,
the one book we got and update it by setting the authors to an array of our objectIds, so of the objectId
of Max and the objectId of Manuel.
And now if we output our books here with findOne,
now we only got the references in there and this is better because now if we do fetch all the books, yeah
we will have to merge it manually with the author data but therefore, the author data is guaranteed to
be up-to-date and if we change the author data, we don't have to do that in hundreds or thousands of documents.