2012-06-19 51 views
21

我要建造我的node.js /快递/ 猫鼬/护照应用,我想正确的架构设计为用户和帐户。MongoDB的架构设计多个auth用户帐户

将有用户从twitter和facebook以及本地帐户登录。在稍后阶段,我希望用户能够将twitter和facebook与我的应用程序(甚至更多的外部帐户)连接起来。

我想不出一个好的解决方案。以下是我正在考虑的选项:

1.拥有配置文件模型和帐户模型。个人资料文档代表唯一用户,而帐户提供用户名和密码(内部帐户)或来自auth-provider(外部帐户)的认证数据。一个配置文件必须至少有一个嵌套帐户文档。

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.Having所有数据单一模式

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

嗯,这只是丑陋-.-可能更容易/更快地找到正确的帐户数据,但它不是对妈妈很好intain。

有没有更好的解决方案? 是否有最佳做法?

+0

与关系数据库不同,使用MongoDB最好的模式设计很大程度上取决于您如何访问数据。您将如何使用帐户数据,以及您将如何访问它? –

+0

我将使用帐户数据与护照进行身份验证。配置文件数据几乎可以在每个页面上以多用途的方式访问。我将通过猫鼬ODM – Sven

+0

访问它。因此,只有在用户登录后才能访问帐户数据,并且一旦发生登录,您将使用会话机制来跟踪登录。 (而不是每个页面访问需要帐户数据。) –

回答

39

1)还有,你可能采取的结构,MongoDB的数据三大战略:

  • 一)扩展到嵌入式文件
  • B)嵌入引用数组
  • C)的阵列母公司文件

策略(a)是您描述的第一个,其中配置文件文件包含帐户子文件数组。 (b)与策略(a)类似,但是您可以使用对其他文档(通常在Account集合中)的引用数组,而不是嵌入实际文档。

策略(c)是您所描述的“在单一模型中拥有所有数据”的策略。

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

有了合适的索引,这个查询就会很快。

+0

写得很好的答案:-)谢谢。我在想那个,但不知道该怎么做。如果可以的话,我会给出更多的观点。再次感谢。 – Sven

+0

我是否应该使用复合稀疏索引? 'ProfileSchema.index({accounts.kind,accounts.uid},{unique:true,sparse:true});'? – CheapSteaks

+0

你应该**不要**使用复合稀疏索引。复合稀疏索引几乎总是不会做你想要的。请为此打开一个新线程。 –