How to design a multi tenant mysql database

老子叫甜甜 提交于 2019-11-27 03:45:17
Mike Sherrill 'Cat Recall'

There are several approaches to multi-tenant databases. For discussion, they're usually broken into three categories.

  • One database per tenant.
  • Shared database, one schema per tenant.
  • Shared database, shared schema. A tenant identifier (tenant key) associates every row with the right tenant.

MSDN has a good article on the pros and cons of each design, and examples of implementations.


Microsoft has apparently taken down the pages I referred to, but they are on on archive.org. Links have been changed to point there.

For reference, this is the original link for the second article

The simple way is: for each shared table, add a column says SEGMENT_ID. Assigned proper SEGMENT_ID to each customer. Then create views for each customer base on the SEGMENT_ID, These views will keep data separated from each customers. With this method, information can be shared, make it simple for both operation & development (stored procedure can also be shared) simple.

Assuming you'd run one MySQL database on a single MySQL instance - there are several ways how to distinguish between what's belonging to whom. Most obvious choice (for me at least) would be creating a composite primary key such as:

CREATE TABLE some_table (
id int unsigned not null auto_increment,
companyId int unsigned not null,
..
..
..,
primary key(id, company_id)
) engine = innodb;

and then distinguishing between companies by changing the companyId part of the primary key. That way you can have all the data of all the companies in the same table / database and at application level you can control what company is tied to which companyId and determine which data to display for certain company.

If this wasn't what you were looking for - my apologies for misunderstanding your question.

Given a specific DB User, you could give a user membership to group(s) indicating the companies whose data they are permitted to access.

I presume you're going to have a Companies table, so just create a one-to-many relationship between Companies and MySQLUsers or something similar.

Then, as a condition of all your queries, just match the CompanyID based on the UserID

Have you considered creating a different schema for each company?

You should try to define more precisely what you want to achieve, though.

If you want to make sure that an HW failure doesn't compromise data for more than one company, for example, you have to create different instances and run them on different nodes.

If you want to make sure that someone from company A cannot see data that belong to company B you can do that at the application level as per Matthew PK answer, for example

If you want to be sure that someone who manages to compromise the security and run arbitrary SQL against the DB you need something more robust than that, though.

If you want to be able to backup data independently so that you can safely backup Company C on mondays and Company A on sundays and be able to restore just company C then, again, a purely application-based solution won't help.

In MySQL I prefer to use a single database for all tenants. I restrict access to the data by using a separate database user for each tenant that only has access to views that only show rows that belong to that tenant.

This can be done by:

  1. Add a tenant_id column to every table
  2. Use a trigger to populate the tenant_id with the current database username on insert
  3. Create a view for each table where tenant_id = current_database_username
  4. Only use the views in your application
  5. Connect to the database using the tenant specific username

I've fully documented this in a blog post: https://opensource.io/it/mysql-multi-tenant/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!