Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

My question is about the architecture of my application. I have a Rails application where companies can administrate all things related to their clients. Companies would buy a subscription and their users can access the application online. Hopefully I will get multiple companies subscribing to my application/service. What should I do with my code and database?

  1. Seperate app code base and database per company
  2. One app code base but seperate database per company
  3. One app code base and one database

The decision involves security (e.g. a user from company X should not see any data from company Y) performance (let's suppose it becomes successful, it should have a good performance) and scalability (again, if successful, it should have a good performance but also easy for me to handle all the companies, code changes, etc).

For the sake of maintainability, I tend to opt for the one code base, but for the database I really don't know. What do you think is the best option?

share|improve this question
    
Why are you editing my question instead of answering? It's confusing now... I would go for the third option for the sake of simplicity, but I have doubts about security. –  John Nov 14 '11 at 17:06

6 Answers 6

I would recommend sticking to a single codebase as best you can unless there are major customizations required by clients that you don't think will be reusable for others. Keeping multiple codebases in sync can turn into a maintenance nightmare, which will only escalate as your client base grows.

As for the database, it's usually best to keep the number to a minimum, but there are a few cases where it makes sense to partition your client data in separate databases:

  1. You have strict (i.e. healthcare or financial industry) requirements on client data confidentiality.
  2. Database performance becomes a problem.

Summary: option 3

share|improve this answer

i would go with option no. 1 because

  • backup & restore per customer is possible out of the box
  • no risk of exposing customer A`s data to customer B due a bug e.g. missing FK in query
  • you can easily scale up or scale out (http://www.codinghorror.com/blog/2009/06/scaling-up-vs-scaling-out-hidden-costs.html), no load-balancer or replicated DB`s needed
  • it is possible to have clients with different versions installed, which comes in handy when you roll out updates. you could/should update 1% of our customers first, if everything goes fine, update the next 10% and after that you update the rest.
share|improve this answer

Personally I would go for the third option. Rails also makes it pretty simple to 'sandbox' the data related to a certain user so that others cannot see it. From a performance point of view having one database to handle all the data can cause queries to be slower but there are numerous ways of improving this.

share|improve this answer

One previous employer started the One app code base but separate database per company model to support different clients, and the clients ended up wanting (and paying for) enough different features that they quickly ended up with Seperate app code base and database per company. So, based on past experiences, I think you'll follow the similar progression. Don't fork customer code bases until you have to, as it is a headache, but rather think about how your practices are and how you'd handle it, then when you are forced into that corner, you already have an idea how to do it.

I'd recommend staying away from One app code base and one database as you may find that customerX wants to take their data and go somewhere else (this might also be a subpoena or search warrant where you have to hand over data in a criminal case and you might not be able to cut out other customers' data). Many companies will prefer this route for risk management because this way a bug in your code will not expose data from other companies (like if you forgot a join, or company ID in one where clause).

share|improve this answer

Personally, I would go with option #1 laced with lots of self-discipline until I had a very, very good understanding of the problem and what parts needed to be extensible on a per-client basis. Given you are starting off, you probably have some ideas as to what you want customizable, but your clients will want to customize things in ways you've never dream of. If you have a single application or a single codebase or both you'll then have to worry about how Client A's special needs impact Client B and vice versa. Having everyone in their own sandbox is a good way to be able to serve the customers, especially early-on when you really need to keep the few customer's you've got. Once the product matures a bit you will have a much better idea of where to build the extensibility points and how to make a single codebase that can serve most customers.

In terms of managing, it really isn't that hard with a bit of discipline. I'm not horribly familiar with ruby so I'm not sure what exact tools one would need to use, but with good scm practices and some automated deployment tools you can keep a handle on management while you are starting out. If you've got nightmares managing this codebase and all the separate apps then you've probably got a good problem to have. Alot better than figuring out how to customize a single monolithic codebase in most cases.

share|improve this answer

I'd recommend the third option for a few reasons.

One code base will make maintenance easier. You may also be able to leverage requests from clients into features other clients would benefit from. If you have a fragmented code base, this will be much more difficult to do and maintain. Not only that, but if you have separate code bases, as soon as you are in a rush, any discipline you had of applying fixes to each individual code base is likely to be forgotten or neglected in your haste.

As for the database, while having multiple databases per client sounds pretty good at this point in the project, as the product grows and matures, you may have one company outpacing the others in terms of usage. This will cause you to have to scale up each individual database separately. If you were using one database for all customers, you only need to scale when overall usage increases. You may run into an issue if one client is MUCH larger than the others, but that can be fixed by sharding your database when the time comes. That could give you the benefit of having a database per client, without the hassle of actually maintaining separate databases.

Another issue with having a single database per customer is -- what happens when you need to change the structure of the database for some reason? Would need to migrate each individual database? While Ruby has tools that help you update databases, I still view multiple migrations as an unnecessary risk.

Unless you have a need to have everything separate, keep everything as similar as possible. For security purposes, just make sure that all calls to the database include a reference to the client that is requesting the data. As long as that rule is enforced (and proper security measures are taken) you won't have to worry about companies seeing each others' data.

share|improve this answer
1  
Although it makes it easy to charge more to that customer. "Your" database needs upgrade of $8000. Here's an invoice. –  Christopher Mahan Nov 16 '11 at 17:10
    
If you are growing to the point where you need to upgrade, I'd hope the cost of the upgrade is more than covered by the growth of the company. However, you are right, if you aren't charging enough for your services any sort of scaling is going to be near impossible. –  David Burhans Nov 16 '11 at 21:50

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.