1 min read

Modifications of the Azure SQL DB structure so it can accommodate the Multitenant architecture

If are just starting to write the application or you are in a re-spinning app cycle, there are some things you need to do in order to make the DB compliant with this scenario.

You will need a tenant table:

CREATE TABLE [dbo].[Tenant](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Name] [nvarchar](250) NOT NULL,
	[CreatedBy] [varchar](100) NOT NULL,
	[CreatedOn] [datetimeoffset](7) NOT NULL,
	[ModifiedBy] [varchar](100) NOT NULL,
	[ModifiedOn] [datetimeoffset](7) NOT NULL,
	[IsDeleted] [bit] NOT NULL,
	[TenantId] [uniqueidentifier] NOT NULL,
 CONSTRAINT [PK_Tenant] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

A user table ( just an example – you can use the current user table structure you have ) :

CREATE TABLE [dbo].[User](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Username] [nvarchar](250) NOT NULL,
	[CreatedBy] [varchar](1000) NOT NULL,
	[ModifiedBy] [varchar](1000) NOT NULL,
	[CreatedOn] [datetimeoffset](7) NOT NULL,
	[ModifiedOn] [datetimeoffset](7) NOT NULL,
	[IsDeleted] [bit] NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] 
GO

And a bridge table between them so you can achieve the N:N cardinality:

CREATE TABLE [dbo].[TenantUser](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[UserId] [int] NOT NULL,
	[TenantId] [int] NOT NULL,
	[CreatedBy] [varchar](100) NOT NULL,
	[CreatedOn] [datetimeoffset](7) NOT NULL,
	[ModifiedBy] [varchar](100) NOT NULL,
	[ModifiedOn] [datetimeoffset](7) NOT NULL,
	[IsDeleted] [bit] NOT NULL,
 CONSTRAINT [PK_TenantUser] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[TenantUser]  WITH CHECK ADD  CONSTRAINT [FK_Tenant] FOREIGN KEY([TenantId])
REFERENCES [dbo].[Tenant] ([Id])
GO

ALTER TABLE [dbo].[TenantUser] CHECK CONSTRAINT [FK_Tenant]
GO

ALTER TABLE [dbo].[TenantUser]  WITH CHECK ADD  CONSTRAINT [FK_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[Users] ([Id])
GO

ALTER TABLE [dbo].[TenantUser] CHECK CONSTRAINT [FK_User]
GO

Now, every time you have a table that has data shared between the tenants you will have to add a new column to the table ( not null is a must ) and also specify a FK to the [dbo].[Tenant] table on [dbo].[Tenant].[TenantId] field.

ALTER TABLE [dbo].[TableWithTenantData] 
ADD [TenantId] uniqueidentifier not null
GO

ALTER TABLE [dbo].[TableWithTenantData] WITH CHECK ADD CONSTRAINT [FK_Tenant] FOREIGN KEY([TenantId])
REFERENCES [dbo].[Tenant] ([TenantId])
GO

ALTER TABLE [dbo].[TableWithTenantData] CHECK CONSTRAINT [FK_Tenant]
GO

At this point you will have your DB ready for this kind of implementation.

Chapter 2 : Modifications of the JWT token generated by the application