Data modeling best practices in Firebase - Time & Space Complexity
When designing data models in Firebase, it's important to understand how the number of operations grows as your data grows.
We want to know how the structure of data affects the speed and cost of reading and writing.
Analyze the time complexity of reading user posts stored in a flat vs nested structure.
// Flat structure example
const postsRef = firebase.database().ref('posts');
postsRef.orderByChild('userId').equalTo(userId).once('value').then(snapshot => {
// process posts
});
// Nested structure example
const userPostsRef = firebase.database().ref(`user-posts/${userId}`);
userPostsRef.once('value').then(snapshot => {
// process posts
});
This code reads posts for a user either by querying a flat list or by reading a nested list under the user.
Look at what happens repeatedly when data grows.
- Primary operation: Reading posts from the database.
- How many times: Number of posts for the user (n).
As the number of posts grows, the time to read them changes depending on the data model.
| Input Size (n) | Approx. Api Calls/Operations |
|---|---|
| 10 | 10 reads in flat query, 1 read in nested |
| 100 | 100 reads in flat query, 1 read in nested |
| 1000 | 1000 reads in flat query, 1 read in nested |
Pattern observation: Flat queries require more operations as data grows; nested reads stay constant.
Time Complexity: O(n) for flat queries, O(1) for nested reads
This means reading data from a flat list grows linearly with the number of items, but reading from a nested path stays constant.
[X] Wrong: "Storing all data in one big list is always simpler and faster."
[OK] Correct: As data grows, queries on big lists become slower and cost more, unlike nested data which can be accessed directly.
Understanding how data structure affects operation cost shows you can design efficient, scalable apps in Firebase.
"What if we indexed the flat list by userId? How would that change the time complexity of reading posts?"