SaaS- Tenant Specific Lookup Data in Shared Databa

2019-03-03 20:17发布

问题:

I am developing multitenant SaaS based application and going with Shared Database for storing all the tenant records with help of TenantId column.

Now the problem is i have some list of lookup records that needs to be shared for all the tenants. For example list of games.

GamesTable

Id
GameName

Also have another table used for storing only tenant specific records

TenantGames

Id
TenantId
GameName  

The basic need is i want to use both table data and get the necessary details (Game_Name) while joining with another transaction table like UserGames. How can i achive this with this design? Here Game_Name can be either referred from Games Shared table or TenantSpecificGames table

Is there any other DB design which allows me to do mix both common master data and tenant master data with JOIN?

Basic requirement is keep common data and allow customization for the tenants if they want to add any new items.

回答1:

This is the design I would then use.

Games

Id
GameName
IsTenantSpecific
SomeGameSpecificColumn

TenantGames

GameId
TenantId
SomeTenantSpecificColumn
AnotherTenantSpecificColumn

Then you can query that table in a Join with:

...
FROM
    Games
    INNER JOIN UserGames ON
        UserGames.GameId = Games.Id
    LEFT JOIN TenantGames ON
        TenantGames.GameId = Games.Id
WHERE
    TenantGames.TenantId = @tenantId OR
    (
        TenantGames.TenantId IS NULL AND
        IsTenantSpecific = 0
    )

Game specific fields can be put in the Games table. Tenant specific fields can be added to the TenantGames table, and those fields will be NULL if it is not a tenant specific customization.



回答2:

We have a saas based database and we keep common data and tenant data in the same table.

Concept

GamesTable

    Id NOT NULL
    TenantId NULL
    GameName NOT NULL
    Add a unique key for TenantId and GameName
  • if TenantId is NULL you know it is common data
  • if TenantId is NOT NULL you know it belongs to a specific tenant and who exactly.

"Is there any other DB design which allows me to do mix both common master data and tenant master data with JOIN?"

Yes

SELECT *
  FROM GamesTable where TenantId = 'your tenant id'
  UNION
SELECT *
  FROM GamesTable where TenantId IS NULL  -- common 


回答3:

This is a classic example of "many to many".

Table: Games
------------
GameID
GameName
IsMasterGame


TennantGames
------------------
GameID
TennantID

Tennants
------------
TennantID
...

To get the games for a given tennant, you would run a query like:

select *
from   Games
where isMasterGame = true
union
select * 
from Games g, 
TennantGames tg
where g.GameID = tg.GameID
and   isMasterGame = false
and   tg.TennantID = $currentTennant

(Apologies for archaic join syntax)

The union allows you to ask two questions: which games apply to everyone (isMasterGame = true), and secondly which games apply to the current tennant (tg.TennantID = $currentTennant). Logically, tennant games cannot also be master games.



回答4:

You can merge the tables leaving TenantId as NULL for records you wish to not be Tenant specific.

Games

Id
TenantId
GameName

The you can query that table in a Join with:

...
FROM
    Games
    INNER JOIN UserGames ON
        UserGames.GameId = Games.Id

WHERE
    Games.TenantId = @tenantId OR
    Games.TenantId IS NULL

This will save you the trouble of ensuring that the Id is unique between the tables, unless you are using a UNIQUEIDENTIFIER for the Id.