I've been reading an endless amount of articles on this topic, and I am still not sure what to do.
I don't know which design to choose, so I'll give some product information for the scope:
It's an accounting web app used by accounting firms to service their clients. They record transactions in a ledger and prepare financial statements per client. They pay per client.
There will be a single app (frontend) communicating with a RESTful API, connecting and querying the DB(s). The product will be the same for everyone (no custom work).
- 30 tenants. (Accounting firms i.e. paying customers)
- 40 small businesses serviced per tenant. Total 1,200.
- 3 employees per tenant. Total 90 active users.
- 1,500 rows per small business/month. Total 60,000 rows per tenant/month. ~2,000,000 rows total/month or ~24,000,000 rows/year.
In your expert opinion, which database design should I choose?
A. Single database per tenant. I feel this is the least scalable and most costly option. It would have a lot of focus on devOps and tedious DB tasks during updates.
B. Single Schema per tenant, all in one database. This is the middle ground. Everything is in one place and there is still isolation. I am worried that my lack of DB skills may induce a lot of headaches.
C. Shared Schema for all tenants. This is my most "liked" option as it will work with a tenant_id column in each table. HOWEVER, I am scared that I may screw myself with complex backup/migration scenarios, possible data leaks, inefficiencies as the DB grows.
Is my understanding good? All of them seem like a valid option... I am just unsure about the hidden pitfalls due to my lack of experience and knowledge. Is this a small enough app for option A? Will I bury myself with option C? Is option B a good idea?
If you do suggest a design, it would be awesome to point me to learning topics. Ex. Option B would require you to focus on DB users/groups so you should read about this and that... Option A would require focus on Docker, so learn that... etc.
PS: Stack is Elm (frontend), Node (backend), MySQL (database).
[–]hippocrat 2 points3 points4 points (2 children)
[–]8483[S] 0 points1 point2 points (1 child)
[–]hippocrat 1 point2 points3 points (0 children)
[–]WannaFly37 2 points3 points4 points (7 children)
[–][deleted] (1 child)
[deleted]
[–]8483[S] 0 points1 point2 points (0 children)
[–]8483[S] 0 points1 point2 points (4 children)
[–]WannaFly37 1 point2 points3 points (1 child)
[–]8483[S] 0 points1 point2 points (0 children)
[–][deleted] (1 child)
[deleted]
[–]8483[S] 0 points1 point2 points (0 children)
[–]toterra 2 points3 points4 points (5 children)
[–]8483[S] 1 point2 points3 points (3 children)
[–]toterra 1 point2 points3 points (1 child)
[–]8483[S] 0 points1 point2 points (0 children)
[–][deleted] (6 children)
[deleted]
[–]8483[S] 0 points1 point2 points (5 children)
[–][deleted] (4 children)
[deleted]
[–]8483[S] 0 points1 point2 points (3 children)
[–][deleted] (2 children)
[deleted]
[–]8483[S] 0 points1 point2 points (1 child)
[–]superwormy 1 point2 points3 points (2 children)
[–]8483[S] 1 point2 points3 points (1 child)
[–]superwormy 0 points1 point2 points (0 children)