web-dev-qa-db-ja.com

マルチテナントMySQLデータベースを設計する方法

複数の企業のデータをホストするデータベースを設計する必要があるとしましょう。次に、セキュリティと管理の目的で、さまざまな会社のデータが適切に分離されていることを確認する必要がありますが、10のサーバーで10の会社のデータをホストするために10のmysqlプロセスを開始したくありません。 mysqlデータベースでこれを行うための最良の方法は何ですか。

31
gaurav

マルチテナントデータベースにはいくつかのアプローチがあります。議論のために、それらは通常3つのカテゴリーに分けられます。

  • テナントごとに1つのデータベース。
  • 共有データベース、テナントごとに1つのスキーマ。
  • 共有データベース、共有スキーマ。テナント識別子(テナントキー)は、すべての行を適切なテナントに関連付けます。

MSDNには、 各設計の長所と短所 、および 実装の例 に関する優れた記事があります。


参考までに、これは 2番目の記事の元のリンク です。

簡単な方法は次のとおりです。共有テーブルごとに、SEGMENT_IDという列を追加します。各顧客に適切なSEGMENT_IDを割り当てました。次に、SEGMENT_IDに基づいて各顧客ベースのビューを作成します。これらのビューは、各顧客からデータを分離し続けます。この方法では、情報の共有が可能で、運用と開発の両方で簡単にできます(ストアドプロシージャも共有できます)。

5
tintinhoking

単一のMySQLインスタンスで1つのMySQLデータベースを実行するとします。何が誰のものであるかを区別する方法はいくつかあります。 (少なくとも私にとっては)最も明白な選択は、次のような複合主キーを作成することです。

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

次に、主キーのcompanyId部分を変更することにより、会社を区別します。これにより、すべての会社のすべてのデータを同じテーブル/データベースに含めることができ、アプリケーションレベルで、どの会社をどのcompanyIdに関連付けるかを制御し、特定の会社について表示するデータを決定できます。

これがあなたが探していたものではなかった場合-あなたの質問を誤解したことをお詫びします。

3
N.B.

MySQLでは、すべてのテナントに対して単一のデータベースを使用することを好みます。データへのアクセスを制限するには、そのテナントに属する行のみを表示するビューへのアクセスのみを持つテナントごとに個別のデータベースユーザーを使用します。

これは次の方法で実行できます。

  1. すべてのテーブルにtenant_id列を追加する
  2. トリガーを使用して、挿入時にtenant_idに現在のデータベースユーザー名を入力します
  3. Tenant_id = current_database_usernameである各テーブルのビューを作成します
  4. アプリケーションでのみビューを使用する
  5. テナント固有のユーザー名を使用してデータベースに接続する

私はこれをブログ投稿で完全に文書化しました: https://opensource.io/it/mysql-multi-tenant/

2
Rob Jenks

特定のDBユーザーを指定して、データへのアクセスが許可されている会社を示すグループにユーザーメンバーシップを与えることができます。

Companiesテーブルがあると思いますので、CompaniesMySQLUsersまたは同様の何かの間に1対多の関係を作成します。

次に、すべてのクエリの条件として、CompanyIDに基づいてUserIDを照合します

1
Matthew

会社ごとに異なる schema を作成することを検討しましたか?

ただし、達成したいことをより正確に定義する必要があります。

たとえば、ハードウェア障害によって複数の会社のデータが損なわれないようにする場合は、異なるインスタンスを作成して、それらを異なるノードで実行する必要があります。

会社Aの誰かが会社Bに属するデータを表示できないようにしたい場合は、Matthew PKの回答に従って、アプリケーションレベルでそれを行うことができます。たとえば、

ただし、セキュリティを危険にさらしてDBに対して任意のSQLを実行した人がいることを確認したい場合は、それよりも堅牢なものが必要です。

データを個別にバックアップして、月曜日に会社Cを、日曜日に会社Aを安全にバックアップし、会社Cだけを復元できるようにしたい場合も、純粋にアプリケーションベースのソリューションは役に立ちません。

1
p.marino