A Car has a Brand. So, many Cars have the same Brand.
How do you do to map these objects to store in the Firestore? What is the best practice for that?
We need to think that a Brand can change, so we need to change the Brand only once to affect all the cars.
Car {
String carName;
Brand brand;
}
Brand {
String brandName;
}
So, what is the best option to store a Car on a Firestore document (no-SQL)?
I think the best option is the 2, so is there any best practice way for it to be performant when reading the data from Firestore?
- Store all cars data:
- Document Car 1:
Car {
carName: "Corolla"
brand: {
brandName: "Toyota"
}
}
- Document Car 2:
Car {
carName: "Land Cruiser"
brand: {
brandName: "Toyota"
}
}
So, "Toyota" brand will repeat in all cars with this brand.
- Reference the Brand document:
- Document Car 1:
Car {
carName: "Corolla"
brand: "abcd-efgh-brand-code"
}
- Document Car 2:
Car {
carName: "Land Cruiser"
brand: "abcd-efgh-brand-code"
}
- Document Brand:
Brand {
documentId: "abcd-efgh-brand-code"
brand: "Toyota"
}
2
Answers
This is Data Normalization
which is concerned with avoiding duplicated data.
Look, for your question both techniques are approximately allocate the same disk space since brand contains only one field (not guaranteed to still have one field in the future), but using the reference technique will definitely prevent data duplication and allow easy brand-update for all cars (docs).
So in the future, changing one doc (brand) will be listened by all docs (Cars), and adding more field in brand doc will save more space comparing with technique 1 (Nested Docs eg: brand inside a car). go ahead and use referenced docs!
As you already showed us in your
Car
class. However, since you only have a single field inside theBrand
class, I cannot see any benefit of using a class in the first place. Besides that, having acar/brand/brandName
it looks redundant to me. So due to the fact that the car brand is a string, then I would change the declaration of theCar
class like this:It would have been if you had used a SQL database. Firestore is a NoSQL database. So holding just a reference to another document might not be the best solution here. Please bear in mind that in NoSQL-type databases there is no concept of a
JOIN
clause. So in order to have faster and cheaper queries, all the data you need to be returned by a query should exist in the documents that are returned.It’s true that you can have a separate distinct collection for the brands if you need to query the brands of the cars separately. However, in this case, having the same data in two different places is a quite common practice. As @FrankvanPuffelen already noticed, it is most likely you have a SQL background. Please remember that in the NoSQL world, we are structuring a database according to the queries that we want to perform. So having the brands inside the car document can be considered totally normal. This technique is called denormalization, and it’s widely used in structuring NoSQL databases. For more information, I recommend reading my answer in the following post: