I’m building a v4 app (Firebase Firestore backend) where a user can buy tags (8-digit alphanumeric characters like 00000001, a1234567, etc).
My question is, how do I store the tags in Firestore? For instance, if someone buys 100 tags (lets say from 00000001 to 00000100), should it create 100 Firestore records (one for each tag, {id:00000001, user:joe@email.com, date:20190101}…), or create just 1 record indicating the last tag purchased, so as to base the next purchase off it {minId:00000001, maxId:00000100, user:joe@email.com, date:20190101}?
I think the first option is better and easier to manage, but costs more due to multiple Firestore read/writes.
Any suggestions will be appreciated.
Thanks.
- The tags are like raffle tickets - one is chosen at the end of every month and given a ‘won’ status
- Bulk purchases don’t have to be contiguous, as long as they’re unique
- Users can’t buy tags by name
- Tags can be transferred to another user
- “Who owns tax X?” is frequent
- “What tags are owned by user Y?” is frequent too
All tags must be unique. Thanks.
OK, I’m going to propose a radically different storage schema, partially just for devil’s-advocate purposes, because I’m hoping that thinking through why this proposal wouldn’t work might shine light on how best to proceed.
There are no more explicit tags, only shares. All you have to store in the database is how many shares are owned by each user. When a user buys a share, the count goes up. When they sell, count goes down. When they transfer, seller’s share count goes down, and buyer’s share count goes up. If the total number of shares sold hits a maximum, every new purchase must be done in the secondary market - IOW, we will refuse to sell more than X shares. The monthly lottery can be done in several ways - one would be to randomly assign each share to a number at drawing time, choose a random number, and see whose share (if anybody’s) got drawn.
This would make for a very compact database, and would be consistent (I think) with all of your answers, with one total exception and one partial one. “Who owns tag X?” would become impossible, so if that can’t be worked around, I guess we’re sunk. “What tags are owned by user Y?” wouldn’t be directly doable, but “How many tags are owned by user Y?” would be, and easy.
This would also make aggregate statistics like “what percentage is still available for purchase?” easy, along with different raffling strategies like “somebody must win every month” (where you limit the drawing to the total number of shares sold).
Imho the design of a nosql like firestore starts with thinking your ui as nosql is also intendended to support fast response times in your ui, not optimising data efficiency nor nested complex queries like in sql
Then redundancy of data including but not limited to like aggregrstes and filteterd lists (eg all tags of a period) or calculations come naturally, either implemented at the client or using functions
If u want mutiple writes and deletes at least use batch to optimise a bit
Wherher u want to store large collections hence dependents on if u need them in the ui and how fast/often
There is no silver bullet as to the level of depth, but shallow is mostly better then deep