2012-06-19 14 views
21

estoy a punto de construir mis Node.js/expresar/mangosta/pasaporte aplicación y estoy pensando en el diseño del esquema derecha para los usuarios y cuentas.MongoDB el diseño del esquema de múltiples cuentas de usuario de autenticación

Habrá usuarios que inicien sesión desde Twitter y Facebook, así como desde cuentas nativas. En una etapa posterior, quiero que un usuario conecte Twitter y Facebook con mi aplicación (y tal vez incluso con más cuentas externas).

No puedo pensar en una buena solución para esa situación. Aquí están las opciones en las que estoy pensando:

1.Teniendo un modelo de perfil y modelos de cuenta. Los documentos de perfil representan el usuario único, mientras que una cuenta proporciona nombre de usuario y contraseña (cuenta interna) o los datos de autenticación del proveedor de autenticación (cuenta externa). Un perfil debe tener al menos un documento de cuenta anidado.

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 
}); 

Lo que no me gusta de ella son los documentos de la cuenta no tan consistentes como resultado de diferentes datos de la cuenta y el hecho de que tengo un tiempo difícil encontrar la cuenta correcta cuando mis usuario inicia sesión (búsqueda fluidos y tipos de cuenta en anidarse documentos -.-)

2.Que tenga todos los datos en un único modelo

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

Bueno, esto es simplemente fea -.- podría ser más fácil/más rápido para encontrar los datos de la cuenta correctos pero no es agradable a ma intain

¿Existe una solución mejor? ¿Existe una mejor práctica?

+0

A diferencia de las bases de datos relacionales, con MongoDB el mejor diseño de esquema depende mucho de cómo va a acceder a los datos. ¿Para qué utilizará los datos de la cuenta y cómo va a acceder a ella? –

+0

Utilizaré los datos de la cuenta para la autenticación con pasaporte. Se accederá a los datos del perfil en casi todas las páginas con fines múltiples. Voy a acceder a ella a través de mongoose ODM – Sven

+0

, de modo que solo se accederá a los datos de la cuenta cuando el usuario inicie sesión, y usted utilizará un mecanismo de sesión para realizar un seguimiento de los inicios de sesión una vez que eso ocurra. (En lugar de necesitar los datos de la cuenta en cada acceso de página.) –

Respuesta

39

1) Hay tres estrategias que usted puede tomar para estructurar los datos en MongoDB:

  • a) Matriz de documentos incrustados
  • b) arreglo de referencias incrustadas
  • c) se expandió a el documento principal

La estrategia (a) es la primera que describe, donde el documento de perfil contiene una matriz de sub-documentos de cuenta.

La estrategia (b) es similar a la estrategia (a), pero utilizaría una serie de referencias a otros documentos (generalmente en una colección de cuentas) en lugar de incrustar los documentos reales.

La estrategia (c) es la que describe como "tener todos los datos en un solo modelo".

2) En general, se considera una mejor práctica para utilizar una matriz de documentos integrados, especialmente si la información que contienen puede variar. Si se le hará la vida más fácil, puede utilizar una clave para distinguir el tipo de la cuenta, así:

{ 
    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 permite realizar una búsqueda en un documento incrustado.Por lo tanto, escribiría la siguiente consulta (sintaxis de JavaScript):

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

Con los índices apropiados, esta consulta será bastante rápida.

+0

Bien escrito respuesta :-) Gracias. Estaba pensando en eso, pero no sabía cómo hacerlo. Daría más de un punto si pudiera. Gracias de nuevo. – Sven

+0

¿Estoy en lo cierto al suponer que debería usar índices compuestos dispersos? 'ProfileSchema.index ({accounts.kind, accounts.uid}, {unique: true, sparse: true});'? – CheapSteaks

+0

Debería ** no ** estar usando índices compuestos dispersos. Los índices dispersos compuestos casi siempre no hacen lo que quieres. Por favor abre un nuevo hilo para esto. –

Cuestiones relacionadas