0

マルチテナント SaaS ベースのアプリケーションを開発しており、TenantId 列を使用してすべてのテナント レコードを格納する共有データベースを使用しています。

問題は、すべてのテナントで共有する必要があるルックアップ レコードのリストがあることです。たとえば、ゲームのリスト。

ゲームテーブル

Id
GameName

また、テナント固有のレコードのみを格納するために別のテーブルを使用する

テナントゲームズ

Id
TenantId
GameName  

基本的な必要性は、UserGames のような別のトランザクション テーブルに参加しながら、両方のテーブル データを使用して必要な詳細 (Game_Name) を取得することです。このデザインでこれを達成するにはどうすればよいですか? ここで、Game_Name は、Games Shared テーブルまたは TenantSpecificGames テーブルから参照できます。

共通マスター データとテナント マスター データの両方を JOIN で混在させることを可能にする他の DB 設計はありますか?

基本的な要件は、共通のデータを保持し、テナントが新しい項目を追加する場合にテナントのカスタマイズを許可することです。

4

4 に答える 4

1

SaaS ベースのデータベースがあり、共通データとテナント データを同じテーブルに保持しています。

概念

GamesTable

    Id NOT NULL
    TenantId NULL
    GameName NOT NULL
    Add a unique key for TenantId and GameName
  • TenantId が NULL の場合、それは共通データであることがわかります
  • TenantId が NOT NULL の場合、それが特定のテナントに属しており、正確には誰であるかがわかります。

「共通マスターデータとテナントマスターデータの両方をJOINで混在させることができるDB設計は他にありますか?」

はい

SELECT *
  FROM GamesTable where TenantId = 'your tenant id'
  UNION
SELECT *
  FROM GamesTable where TenantId IS NULL  -- common 
于 2012-10-19T00:24:15.823 に答える
1

その時に使うデザインです。

ゲーム

Id
GameName
IsTenantSpecific
SomeGameSpecificColumn

テナントゲームズ

GameId
TenantId
SomeTenantSpecificColumn
AnotherTenantSpecificColumn

次に、結合でそのテーブルをクエリできます。

...
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
    )

ゲーム固有のフィールドを Games テーブルに入れることができます。テナント固有のフィールドを TenantGames テーブルに追加できます。テナント固有のカスタマイズでない場合、それらのフィールドは NULL になります。

于 2012-10-22T23:09:40.460 に答える
0

テナント固有にしたくないレコードの TenantId を NULL のままにして、テーブルをマージできます。

ゲーム

Id
TenantId
GameName

Join でそのテーブルをクエリできます。

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

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

これにより、ID に UNIQUEIDENTIFIER を使用していない限り、ID がテーブル間で一意であることを確認する手間が省けます。

于 2012-10-22T12:35:22.690 に答える
0

これは「多対多」の典型的な例です。

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


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

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

特定のテナントのゲームを取得するには、次のようなクエリを実行します。

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

(古い結合構文についてのお詫び)

組合では、2 つの質問をすることができます: どのゲームが全員に適用されるか ( isMasterGame = true)、次にどのゲームが現在のテナントに適用されるか ( tg.TennantID = $currentTennant)。論理的には、テナント ゲームがマスター ゲームになることはありません。

于 2012-10-16T09:24:49.907 に答える