web-dev-qa-db-ja.com

複数の認証ユーザーアカウント用のMongoDBスキーマ設計

Node.js/express /mongoose/passportをビルドしようとしています)アプリケーションと私はユーザーとアカウントの正しいスキーマ設計について考えています。

TwitterやFacebook、ネイティブアカウントからログインするユーザーがいます。後の段階で、ユーザーがTwitterとFacebookの両方を自分のアプリケーション(および場合によってはさらに多くの外部アカウント)に接続するようにします。

私はその状況に対する良い解決策を考えることができません。これが私が考えているオプションです:

1.プロファイルモデルとアカウントモデルを持っている。プロファイルドキュメントは一意のユーザーを表し、アカウントはユーザー名とパスワード(内部アカウント)または認証プロバイダーからの認証データ(外部アカウント)のいずれかを提供します。プロファイルには、少なくとも1つのネストされたアカウントドキュメントが必要です。

var ExtAccountSchema = new Schema({
    type: String, // eg. Twitter, facebook, native
    uid: String
});

var IntAccountSchema = new Schema({
    username: String,
    password: String
});

var ProfileSchema = new Schema({
    firstname: String,
    lastname: String,
    email: String,
    accounts: [Account] // Pushing all the accounts in there
});

私が嫌いなのは、異なるアカウントデータに起因する一貫性のないアカウントドキュメントと、ユーザーがログインしたときに適切なアカウントを見つけるのに苦労しているという事実です(ネストされたドキュメントでuidとアカウントタイプを検索する-.-)

2.すべてのデータを単一のモデルに含める

var ProfileSchema = new Schema({
    firstname: String,
    lastname: String,
    email: String,        
    Twitter-uid: String,
    facebook-uid: String
    password: String
});

まあこれは醜いです-.-正しいアカウントデータを見つけるのは簡単/速いかもしれませんが、維持するのはいいことではありません。

より良い解決策はありますか? ベストプラクティスはありますか?

31
Sven

1)MongoDBでデータを構造化するために取る可能性のある3つの戦略があります。

  • a)埋め込まれたドキュメントの配列
  • b)埋め込まれた参照の配列
  • c)親ドキュメントに展開

戦略(a)は、最初に説明する戦略であり、プロファイルドキュメントにはアカウントサブドキュメントの配列が含まれています。

戦略(b)は戦略(a)に似ていますが、実際のドキュメントを埋め込むのではなく、他のドキュメント(通常はアカウントコレクション内)への参照の配列を使用します。

戦略(c)は、「すべてのデータを1つのモデルにまとめる」と説明するものです。

2)埋め込まれたドキュメントの配列を使用することは、特にそれらの情報が異なる可能性がある場合は、一般的にベストプラクティスと見なされます。それがあなたの生活を楽にするなら、あなたは次のようにアカウントのタイプを区別するためにキーを使うことができます:

  { 
    firstname: 'Fred',
    lastname: 'Rogers',
    email: '[email protected]',

    accounts: [
             { kind: 'facebook',
               uid: 'fred.rogers'
             },
             { kind: 'internal',
               username: 'frogers',
               password: '5d41402abc4b2a76b9719d911017c592'
             },
             { kind: 'Twitter',
               uid: 'fredr'
             }
          ]
    }

3)MongoDBを使用すると、埋め込まれたドキュメントを検索できます。したがって、次のクエリ(JavaScript構文)を記述します。

 db.profile.find( 
        { email: '[email protected]', 'accounts.kind': 'facebook' }
        );

適切なインデックスがあれば、このクエリは非常に高速になります。

48
William Z