web-dev-qa-db-ja.com

1つのSQLサーバーに配置できるデータベースの数に制限はありますか?

私はSaaSシステムをセットアップしています。ここでは、各顧客に独自のデータベースを提供する予定です。システムはすでにセットアップされているので、負荷がかかった場合、追加のサーバーに簡単にスケールアウトできます。大きくなりすぎて、私たちは何千、何万という顧客を獲得したいと考えています。

ご質問

  • 1つのSQL Serverで使用できる/すべきマイクロデータベースの数に実際的な制限はありますか?
  • サーバーのパフォーマンスに影響はありますか?
  • それぞれ100 MBのデータベースを10,000個持つのと、1 TBのデータベースを1個持つのとどちらが良いのでしょうか。

追加情報

「マイクロデータベース」と言っても、「マイクロ」という意味ではありません。私たちは単に数千の顧客を対象としているので、個々のデータベースはデータストレージ全体の1000分の1以下になるだけです。実際には、各データベースは、使用量に応じて100MB程度になります。

10,000データベースを使用する主な理由は、スケーラビリティのためです。事実、システムのV1には1つのデータベースがあり、DBが負荷の下で緊張しているときに、不快な瞬間がありました。

CPU、メモリ、I/Oに負担をかけていました-上記すべて。これらの問題を修正したとしても、世界で最高のインデックスを作成していても、期待どおりに成功した場合、すべてのデータを1つの大きな本管に入れることはできないことに気づきました。 'データベース。 V2ではシャーディングを行っているため、複数のDBサーバー間で負荷を分散できます。

私は昨年、この分割ソリューションの開発に費やしました。これはサーバーごとに1つのライセンスですが、AzureでVMを使用しているので、いずれにせよそれが処理されます。今問題が出てくるのは、以前は私たちが大規模な機関にのみ提供し、それぞれを自分たちで設定していたからです。私たちの次の業務は、ブラウザを持っている人なら誰でもサインアップして独自のデータベースを作成できるセルフサービスモデルです。彼らのデータベースは、大規模な機関よりもはるかに小さく、はるかに多くなります。

Azure SQL Database Elastic Pools を試しました。パフォーマンスは非常に期待外れだったので、通常のVMに切り替えました。

43
Shaul Behr

私は、1つのインスタンスで8〜10千のデータベースを使用するSQL Serverで作業しました。きれいじゃない。

サーバーの再起動には、1時間以上かかることがあります。 10,000個のデータベースの回復プロセスについて考えてみます。

SQL Server Management Studioを使用して、オブジェクトエクスプローラーでデータベースを確実に見つけることはできません。

バックアップに価値があるためには、実用的な災害復旧ソリューションを導入する必要があるため、バックアップは悪夢です。うまくいけば、あなたのチームはスクリプト作成が得意ですすべて

M01022T9945のように、データベースに番号を付けるなどの作業を開始します。正しいデータベースで作業していることを確認しようとします。 M001022の代わりにM01022を使用すると、混乱する可能性があります。

その多くのデータベースにメモリを割り当てるのは大変なことです。 SQL Serverは大量のI/Oを実行することになり、パフォーマンスが大幅に低下する可能性があります。 10,000社の4つのテーブルにわたって炭素使用量の詳細を記録するシステムを考えてみましょう。 1つのデータベースでこれを行う場合、必要なテーブルは4つだけです。これを10,000のデータベースで実行すると、突然、メモリ内に40,000のテーブルが必要になります。メモリ内のその数のテーブルを処理するオーバーヘッドはかなりのものです。これらのテーブルに対して実行されるクエリを設計する場合、10,000個のデータベースが使用されている場合、プランキャッシュに少なくとも 10,000個のプランが必要です。

上記のリストは、そのような規模で運用する場合に計画する必要がある問題のほんの一部です。

おそらく、SQL Serverサービスの起動に非常に長い時間がかかるため、サービスコントローラーエラーが発生する可能性があります。サービスの起動時間を自分で増やすには、次のレジストリエントリを作成します。

サブキー:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control 
名前:ServicesPipeTimeout 
タイプ:REG_DWORD 
データ:サービスの起動中にタイムアウトが発生するまでのミリ秒数

たとえば、サービスがタイムアウトする前に600秒(10分)待機するには、600000と入力します。


私の回答を書いてから、質問がAzureについて話していることがわかりました。おそらく、SQLデータベースでこれを行うことはそれほど問題ではありません。おそらくもっと問題があります。個人的には、おそらく単一のデータベースを使用して、おそらく複数のサーバー間で垂直に分割されたシステムを設計しますが、顧客ごとに1つのデータベースはありません。

80
Max Vernon

したがって、どちらの方法にも長所と短所があります。あなたが提供しようとしているあなたのアプリケーションやサービスについてもっと知らなければ、私は決定的な答えを出すことができませんが、私はその問題についての私の考えのいくつかを捨てます。

すべてのクライアントに1つのデータベースを使用する理由についての私のケース。

長所

  • 簡単なメンテナンス。 1つのDBを持つことは、多くの場所ではなく1つの場所でメンテナンスタスクを実行するだけでよいことを意味します。バックアップする1000の異なるデータベースを処理するという悪夢を想像してみてください。 1000 DBの統計を更新するか、インデックスを再構築するか、DBCC CHECKDB

  • コードのデプロイ。アプリケーションコードまたはレポートのストアドプロシージャに問題があるとします。簡単な変更を加える必要があります...次に、その変更を1000以上のDBに展開する必要があります。いいえ、結構です。

  • 簡単な表示。 SSMSが1000以上のDBを開こうとしているだけの画像(震動)。それは実際に問題を役に立たなくし、S​​SMSを開いてレンダリングするのに驚くほどの時間がかかります。適切な命名規則を思い付くことができる場合に注意してください。

短所

  • セキュリティ。他の顧客のデータを個別のDBとして持っていると、他の顧客のデータを見られないようにする方が簡単です。ただし、これが起こらないようにするためにできる非常に簡単なことがいくつかあります。

  • パフォーマンス。顧客ごとに1つのDBに制限すると、SQLサーバーは、より少ないデータをスキャンするだけで、クエリしている情報を取得できるようになります。ただし、適切なデータ構造と適切な索引付け(および可能なパーティション化)を使用すると、注意深く行えば、問題としてこれをすべて取り除くことができます。そのオーバーヘッドを削減するために、顧客固有のデータを含む各テーブルに何らかの先行CompanyIDを与えることをお勧めします。

結局のところ、最善の策は、アプリケーション用に1つのDBを用意し、DB自体の内部で顧客データを分割することだと思います。 1000以上のデータベースを管理するという悪夢に比べれば、問題は何もありません。

19
Zane

SQL Serverの最大容量仕様 は、32,767の制限があることを示しています。

パフォーマンスに影響を与えるかどうかについては答えは「はい」ですが、パフォーマンスに影響を与える方法と、それが実質的になるかどうかは、無数の要因によって異なります。

10,000のデータベースに分割する正当な理由がない限り、1つのデータベースを使用します。 1つのバックアップまたは10,000のバックアップ? 1つの整合性チェック、または10,000? 10,000個の小さなDBを使用するのには十分な理由があるかもしれませんが、それを判断するための十分な詳細がありません。あなたが尋ねた質問はかなり広範で、誰もが最良の答えが何であるかを知るのに十分な情報がありません。

17
Tony Hinkle

ここで話しているのは、マルチテナントvsマルチインスタンスです建築。これらの用語は質問で使用しないので取り上げますが、これはあなたが話していることであり、「マルチテナントアーキテクチャ」をGoogleにプラグインするだけで、豊富なリソースと議論が見つかります。それについては、本全体が書かれています。

ここにSQL Serverに関するいくつかの優れたリソースがあります。

https://msdn.Microsoft.com/en-us/library/ff966499.aspx

https://docs.Microsoft.com/en-us/Azure/sql-database/sql-database-design-patterns-multi-tenancy-saas-applications

マルチインスタンスを支持する説得力のある理由がない限り、デフォルトとしてマルチテナントに強く傾けます。

スケーリングするために数千の個別のクライアントデータベースに分割する必要はありません。それを行う方法は他にもたくさんあります。クラスタリング、レプリケーション、シャーディング、パーティショニングなどのように、ホイールを再発明しないでください。これを手動で個別の顧客レベルで分割する必要があると言う本質的なことは何もありません。実際、これを行うと、すべての新しい顧客を追加するコストが大幅に増加する可能性があります。

あなたは「何百万もの」顧客について話している、サービスとしての大規模なクラウドベースのソフトウェア、Gmailなどを考えています。彼らは新しい登録ごとに完全に新しいデータベースを作成しているとは思いませんか?

たとえば、自社のインフラストラクチャで社内でホストする必要がある顧客に製品を販売している場合など、これを容易にしたい場合があります。ただし、一般的なSAASルールとして、デフォルトとしてマルチテナントアーキテクチャに傾けます。

7
Ivan McA

単一データベースの提案に対して私が見ることができる欠点の1つは、データのロールバックを行うことです。テナントごとにデータベースが設定されている場合は、各クライアントのデータを個別に(および特定の時点まで)復元できます。それらがすべて1つのデータベース内にある場合、これは非常に困難になります(INSERT/UPDATE/DELETEステートメントを介して実行する必要があるため、エラーが発生しやすくなります)。

7
Darshan

答えてくれたすべての人に感謝します-あなたが考えてくれた点を本当に感謝しています。私が得た一般的な感覚は、単一のデータベースが望ましいということでしたが、シャーディングされたアーキテクチャーを支持するためにいくつかの相殺ポイントを追加し、他の人々が述べた懸念のいくつかに対処したいと思います。

シャーディングの動機

(更新された)質問で述べたように、私たちは文字通り数百万人のユーザーによる世界中での大規模な販売を目指しています。世界最高のハードウェアとインデックス作成機能を備えた単一のDBサーバーは負荷をかけないため、複数のサーバーに分散できる必要があります。そして、特定の顧客のデータがどのサーバーにあるかを調べなければならない場合、専用のデータベースを提供するのはそれほど簡単ではありません。これにより、人々のデータを適切に分離するという点で物事がより簡単になります。

懸念への対応

  • サーバーの再起動には時間がかかります: OK、しかし通常の操作ではサーバーを再起動するつもりはありません。システムは最終的には24時間年中無休でオンラインである必要があるため、ダウンタイムが発生する場合は、とにかくスケジュールする必要があります。
  • バックアップ/災害復旧:すべてを自動化するCloudBerryを使用しています。問題ない。
  • データベースに名前を付ける/ SSMSでそれらを見つける:命名規則は顧客名に基づいて簡単です。名前が共有されている場合は、シリアル番号を追加します。
  • Maintenance:各データベースが想定しているほど小さい場合、手動でインデックスを再構築する必要はありません。
  • コードの展開:エンティティフレームワークを使用しているため、スキーマの変更はすべて、新しいリリースで各データベースに自動的にロールアウトされます。ただし、単純なインデックスTweakで修正できる本番環境でパフォーマンスの問題を発見した場合、それをそこにプッシュするだけではそれほど簡単ではありません。一方、各データベースが非常に小さいため、運用シャードでパフォーマンスの問題が発生する可能性はほとんどありません。また、共通データベースは単一のDBのままであり、これらの懸念は適用されません。

何か不足していると思われる場合は、コメントでご連絡いたします。

6
Shaul Behr