Fog CreekFogbugz の顧客ごとにデータベースを使用することを、stackoverflowポッドキャストから覚えています。これは、Fogbugz On Demandサーバーに数万のデータベースがあることを意味します。
Webアプリの開発を始めたばかりで、同様の問題を解決する必要があります(多くの顧客が独自の分離データを持っています)。
顧客ごとにデータベースを使用する場合、どのような問題が予想されますか?どうすれば解決できますか?
顧客ごとのデータベースの利点
欠点
このソリューションはマルチテナント設計と呼ばれ、各テナント(顧客)は独自のデータベースを持っています。そのため、単一のデータベースである別のアプローチには、他にもいくつかの考慮事項があります。
別のデータベースがあることは、データベースのバージョンをアプリケーション/サイトのバージョンと一致させる更新メカニズムを構築する必要があることを意味します。ただし、個別のデータベースはデータの優れた分離を提供し、IMOはホスティングのコストが低くなります。すべてのシナリオに対応できるわけではありません。システムがホスティングの外部でホストされることはなく、顧客を迅速にスケールアップする必要があり、すべてのユーザーが同じバージョンのアプリケーションとデータベーススキーマを使用することが望ましい場合は、単一のデータベースを使用することをお勧めします。
私の経験では、顧客ごとに1つのデータベースを作成するべきではありません。例を挙げましょう。
昨年私は70のデータベース(5000をはるかに下回る)を使用し、それぞれが同じスキーマとすべてを使用していました。理論的には、(利点のセクションで説明したように)計画どおりに進みますが、実際にはそれほどではありません。スキーマの更新、ユーザーサポート、ソフトウェアの更新に関して多くの問題がありました。それはひどかったです。
私たちはFirebirdを使用しており、製品の出荷後に採用されましたが、これにより、別々のデータベースを使用しないでください。
私はあなたがそれを引き出すことができないと言っているわけではありません、私は物事は非常にうまくいかない可能性がありますと言っています。それらのほとんどは、単一のデータベースで実行できます。
別のデータベースを保持して各顧客のバージョンを追跡したい場合があるため、最後の変更が行われたか、行われていないかを追跡できます。
アップグレードのスクリプトを作成することはそれほど難しくありません...データベースのカタログを調べ、必要な変更を適用して各データベースを最新バージョンにして、何らかの理由でアップグレードしてはならないものをスキップするようなものを書くことができます。
Mysqlの「データベース」は単なるスキーマなので、Gaiusが指摘したように、すべてが同じサーバーインスタンスから実行されている場合は、変更しようとしているテーブルの名前を修飾するか、次の情報を取得できます。
alter schema.table ...
select ... from schema.table
...
複数のサーバー間で物事を分割し始めた場合でも、複数のサーバーに接続するスクリプトを作成して、すべての変更を適用できます。分析の場合も、マスターデータベースで federated tables を使用して一連のデータベースリンクを設定し、テーブルから読み取るだけなので、1つの場所からデータにアクセスできます。
...
また、スタック交換にmySQLを使用していないこと、SQL Serverを使用していることにも注意してください。
そして、そのスケールでmysqlにどのようなパフォーマンスオーバーヘッドが発生するかはわかりません。mysqlで30の「データベース」を超えたことはないと思います。
同じ数のテーブル(162)と同じテーブル構造を持つ750以上の顧客データベースを持つWeb/DBホスティングクライアントがあります。結合すると、クライアントの顧客データはすべて合計524GB(95%InnoDB)
これらすべてのデータベースが、循環レプリケーションを介して9つのDBサーバーで13Gのinnodbバッファープールをめぐって競合していると想像してください。そのハードウェア構成でスケールアウトするだけでは不十分でした。すぐに、私たちはクライアントにスケールアップすることを勧めました。
私たちは最近、このクライアントをはるかに高い処理能力を持つ3つのDBサーバーに移行しました(高コスト環境ではSSDを避けてください、常に!!!)。 MySQL 5.0.90からMySQL 5.5.9にアップグレードしました。劇的な違いがほぼ瞬時に見られました。
数百のクライアントが同じメモリとディスクリソースにアクセスしている場合、スケールアウトは線形に使用量を削減するため(O(n))、nはマルチマスター環境のDBサーバーの数に基づいているため、スケールアウトも考慮する必要があります。
私のクライアントの場合、私の会社は彼をMySQL 5.5の9台のDBサーバー(クアッドコード、32GB RAM、824G RAID10)からより高速なDBサーバー(デュアルHexaCore [それはまさに12 CPU]、192GB RAM、1.7TB RAID10)に減らしています。 .9(表では、複数のCPUを利用しています)。さらに、それぞれ3 GBの50パーティションに150 GBのinnodbバッファープールがあるとします(複数のInnoDBバッファープールはMySQL 5.5の新機能です)。小規模なスケールアウトですが、大規模なスケールアップが、クライアントの独自のインフラストラクチャで機能していました。
ストーリーのモラル:不適切に設計されたテーブルがある場合、スケールアップまたはスケールアウトは常に解決策とは限りません。つまり、インデックスページにマルチカラムインデックスのキー集団が偏っている場合、インデックスの偏った部分からキーをクエリすると、テーブルスキャン後にテーブルスキャンが発生するか、少なくともMySQLクエリによって除外されているために使用されないインデックスが発生します。オプティマイザ。適切な設計に代わるものはありません。
MySQLは個別のディレクトリにデータベースを作成するため、基になるオペレーティングシステムと、それが処理できるフォルダー/ファイルハンドルの数に大きく依存します。最新のオペレーティングシステムでは問題になりませんが、ボトルネックの多くはそこから発生します。
異なるバージョンのデータベースまたはアプリをホストする必要があるということは何もありません。顧客ごとに1つのdbを実行し、1つのバージョンのデータベースとアプリを用意するだけでデータを分離することの何が問題になっていますか?もちろん、各顧客データベースは、現在の作業バージョンのテンプレートから複製する必要があります。セキュリティとデータ分離の観点から、これは理想的だと思います。
私が目にできる唯一の欠点は、新しいバージョンを作成するときに各データベースを手動で更新する必要があることです。これは簡単に自動化できます。