Reputation: 1165
I'm building a multi-tenant app (single database, single schema) using ASP.NET Web Api, Entity Framework and SQL Server / Azure database.
This app will be used by 1000-5000 customers. All the tables will have a TenantId
(Guid
) column. Right now, I use single column primary key which is Id
(Guid
).
The problem with that is, I have to check if the data supplied by the user is from / for the right tenant. E.g I have a sales order table which has a CustomerId
column. Everytime user post/update sales order, I have to check if the CustomerId
is from the same tenant.
It gets worse because each tenant might have several outlets. Then I have to check TenantId and OutletId. It's really a maintenance nightmare and bad for performance.
I'm thinking to add TenantId
as primary key along with Id
. And possibly add OutletId
too. So primary key in sales order table will have multiple columns, Id
, TenantId
, OutletId
.
What is the downside of this approach? Would the performance hurt badly using composite key? Does the composite key order matter? Are there better solution for my problem?
Upvotes: 0
Views: 1596
Reputation: 5819
If you want to use a composite key please use always (if possible) all elements of the key to avoid index range scans
The order of elements is important. If you want to retrieve for example all data related to a single tenant (see pt. 1) you should use TenantId
as the first element (see Why does primary key order matter?)
For Azure SQL you should also consider concepts like Elastic Scale or partitioning for legacy systems which could improve performance.
Do you really need a guid for the TenantId? If you have a limited amount of customers (<= 5000 is not that much) you could also use a int (or even int64) type which would allow easier partitioning (see pt. 3)... I do like guids a lot, but for ease of maintenance and if I do not need the big range for data I try to avoid them (see this article for performance). If you need the tenant id in advance, you can use sequences (a new feature for SQL Azure V12):
create sequence CustomerSequence as int
start with 0
increment by 1;
select next value for CustomerSequence;
EDIT: Added information about sequences in SQL Azure
Upvotes: 2