web-dev-qa-db-ja.com

ユーザーとユーザープロファイルを異なるテーブルに保持しますか?

私はいくつかのプロジェクトで、開発者が重要なユーザー情報を1つのテーブル(メール/ログイン、パスワードハッシュ、スクリーン名)に保持し、残りの重要でないユーザープロファイルを別のテーブル(作成日、国など)に保持することを好みました。本質的ではないということは、このデータはたまにしか必要とされないということです。明らかな利点は、ORMクエリを使用している場合、より少ないフィールドが明らかに良いことです。ただし、2つのエンティティを同じテーブルにマップすると、不要なものをクエリする必要がなくなります(便利です)。これらのものを2つのテーブルに保持することの他の利点を誰かが知っていますか?

26
Andrey

プロジェクトのサイズと要件によって異なります。

ユーザーに関するデータを、目的と要件が異なる2つのセットに分割する1つの方法を確認できます。

  • IDデータ:ユーザー名、パスワードハッシュ、電子メールアドレス、最終ログイン時間など.
  • ユーザー設定、最新のアクティビティ、ステータスの更新などを含むユーザープロファイルデータ.

どちらのカテゴリにも該当する可能性のあるユーザーの属性がいくつかあることに注意してください(例:ユーザーの生年月日)。ただし、これら2つのセットの違いは、最初のセットは厳密に制御されており、特定のワークフローを通じてのみ変更できることです。たとえば、パスワードを変更するには既存のパスワードを入力する必要があり、メールを変更するとメールの確認が必要になる場合があります。これは、ユーザーがパスワードを忘れた場合に使用されます。

プリファレンスにはそのようなACLは必要ありません。ユーザーが同意する限り、理論的にはユーザーまたは別のアプリケーションによって変更できます。アプリケーションが故意に、またはバグが原因でデータが破損したり、変更を試みたりした場合(他のセキュリティ対策が講じられていると想定)、危険度は低くなります。それらは、ユーザーのIDを引き受けるか、サービスを拒否するか、管理者にサポート費用などをもたらすために使用できるためです。

したがって、通常、データは2種類のシステムに保存されます。

  • IDデータは通常、ディレクトリまたはIAMソリューションに格納されます。
  • 設定データは最終的にデータベースに入れられます。

そうは言っても、実際には人々はこれらのルールに違反し、どちらか一方を使用します(ASP.NETメンバーシッププロバイダーの背後にあるSQLサーバーなど)。

IDデータが大きくなるか、それを使用する組織が大きくなると、さまざまな種類の問題が侵入します。たとえば、ディレクトリの場合、マルチサーバー環境のすべてのサーバーにパスワードの変更をすぐに複製しようとします。ただし、ユーザー設定には結果整合性のみが必要です。 (参考:これらは両方とも、CAPS定理の異なる最適化です。)

最後に、ディレクトリ(特にonline/cloudディレクトリ)は、OAUTH(たとえば、Facebook、Google、Microsoftアカウント、ADFSを考慮する)などのプロトコルを使用して他のリソースのアクセストークンを発行しますが、データベースそのような必要はありません。データベースは、ディレクトリが必要としない、非常に複雑な結合とクエリ構造をサポートします。

詳細については、アイデンティティディレクトリとデータベースを数回検索すると役立ちます。

最終的には、サードパーティとの統合(およびサードパーティが使用しているもの)を含め、シナリオが将来あると予想されるものになります。それが十分に含まれているプロジェクトであり、ユーザーIDデータを保護し、正しく認証できると確信している場合は、データベースを使用できます。それ以外の場合は、IDディレクトリを調査する価値があります。

DBの場合、IMOでは、1つのDBと2つのDBを使用すると、最終的にはユーザーとアプリケーションの両方のアクセス制御が低下します。

12
Omer Iqbal

基本属性の個人テーブルと、1対1の関係を持つ他の属性の2番目のテーブルが望ましい場合、少なくとも3つのケースがあります。

  • BLOBデータのような画像。別個のテーブルを使用すると、パフォーマンス上の理由から、たとえば別個のテーブルスペースにデータを個別に格納できます。
  • 全員に当てはまらない、または特定の役割を果たしている人にのみ当てはまるデータ。 メインテーブルの一部である場合、多くの行でnullになる列と考えてください。クリニックのデータベースでは、個人テーブル、患者テーブル、およびメディックテーブル。最初のテーブルには基本的な属性があり、2番目のテーブルには、個人が保険のように患者である場合にのみ関連する属性、3番目のテーブル(個人がメディックの場合)があります。あなたは、医療専門家と医療従事者にのみ適用される他のデータを持つことができます。明らかに、衛生兵は患者になることができます。
  • リモートシステム内のエンティティとの関係を具体化するテーブル。この場合、相互運用性の理由から、テーブルは個別のデータベース内の一意の識別子間の同等性を確立します。

あなたが公開するケースは2番目のケースに収まると思います。

3

それらを分離しておく主な理由は、オブジェクト指向プログラミングで「神のクラス」として知られているものを試して回避するためです。 ORMはテーブルとフィールドをクラスと属性に関連付けます。そのため、SQLレベルとしても関連性があります(ORMがなくても、一般的に同様の原則が機能します)。

Userクラス(およびユーザーテーブルとの関連付け)は、多くの場合、数百の属性/フィールド、数十または数百のメソッド、および1000行を超えるクラス定義(メソッド用)を持つ神クラスになるテーブルです。私はそれをすべて見ました。一回以上。

したがって、ユーザーからの分離はそれに対処しようとします。人、ユーザー、アカウントがあり、懸念の分離は少し人工的なように見えるかもしれませんが、複雑さを回避して、各オブジェクトがデータの1つの側面のみに関係するようにすることです。

1
Michael Durrant