多身份验证用户帐户的MongoDB模式设计
我即将构建node.js/express/mongoose/passport应用程序,我正在考虑为用户和帐户设计合适的模式 将有用户从twitter和facebook以及本地帐户登录。在以后的阶段,我希望用户能够将twitter和facebook与我的应用程序(甚至更多的外部帐户)连接起来。 我想不出解决这种情况的好办法。以下是我正在考虑的选项: 1.有档案模型和账户模型。配置文件文档表示唯一用户,而帐户提供用户名和密码(内部帐户)或来自身份验证提供程序(外部帐户)的身份验证数据。配置文件必须至少有一个嵌套的帐户文档多身份验证用户帐户的MongoDB模式设计,mongodb,express,mongoose,passport.js,Mongodb,Express,Mongoose,Passport.js,我即将构建node.js/express/mongoose/passport应用程序,我正在考虑为用户和帐户设计合适的模式 将有用户从twitter和facebook以及本地帐户登录。在以后的阶段,我希望用户能够将twitter和facebook与我的应用程序(甚至更多的外部帐户)连接起来。 我想不出解决这种情况的好办法。以下是我正在考虑的选项: 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
});
这太难看了-找到正确的帐户数据可能更容易/更快,但维护起来并不好
有更好的解决办法吗是否有最佳实践?1)在MongoDB中构建数据结构时,您可以采取三种策略:
- a) 嵌入文档数组
- b) 嵌入引用数组
- c) 展开到父文档中
{
firstname: 'Fred',
lastname: 'Rogers',
email: 'fred.rogers@example.com',
accounts: [
{ kind: 'facebook',
uid: 'fred.rogers'
},
{ kind: 'internal',
username: 'frogers',
password: '5d41402abc4b2a76b9719d911017c592'
},
{ kind: 'twitter',
uid: 'fredr'
}
]
}
3) MongoDB允许您搜索嵌入的文档。因此,您将编写以下查询(JavaScript语法):
有了适当的索引,这个查询会非常快。我希望它能帮助像您这样有类似需求的人 MongoDB中的模式设计和数据建模
- SQL具有固定/严格的模式,而NoSQL具有动态/灵活的模式,即不强制文档结构
- MongoDB有两种类型的数据模型:
- 嵌入式数据建模:
- are具有单一文档结构,被称为非规范化模型
- 支持文档级原子操作
- 易于执行的积垢
- 70%的情况下使用,读操作性能高
- 大小很容易达到其阈值,即16MB,并且容易出现高冗余
- 在一对一和一对多关系中推荐
- 引用或链接数据建模:
- 模仿SQL数据库的规范化表以减少数据重复和冗余
- reference或_id用于引用另一个文档,类似于使用主键和外键连接SQL中的表
- 在30%的情况下使用
- 在多对多关系中推荐
- 嵌入式数据建模:
- 概念数据建模:关于功能和服务的大图,其中还包括
- ER数据建模:数据库设计的图形化方法
- 模式设计
- 逻辑数据建模:概念数据建模将使用编程语言、表格等转换为逻辑数据建模(程序)(服务器代码)
- 物理数据建模:在用户插入实际数据的情况下,将逻辑数据管理付诸实践。(数据库)
- 平面、星形、层次、关系、对象关系
- 通常,您应该构造模式,以便应用程序在一次读取操作中接收所有必需的信息
- 在设计模型方面,它也基于与一对一相同的概念
- 在某些情况下,最好使用参考模型以获得更好的性能,如下所示
- 为避免出版商数据重复,请使用参考资料,并将出版商信息与图书集分开存放
- 如果未来books数组可能会变得巨大,那么最好将publisher引用存储在book文档中
- 观察模式中的智能变化,了解
信息(即出版商id)在藏书中如何被称为\u id
出版商id
与关系数据库不同,MongoDB的最佳模式设计在很大程度上取决于如何访问数据。您将使用帐户数据做什么?您将如何访问它?我将使用帐户数据与passport进行身份验证。配置文件数据将访问几乎每一页的多功能用途。我将通过mongoose访问它,ODMSo帐户数据只有在用户登录时才会被访问,而一旦发生这种情况,您将使用会话机制来跟踪登录情况?(与每页访问都需要帐户数据相反)我需要每页的用户数据。但我不知道该怎么做
db.profile.find(
{ email: 'fred.rogers@example.com', 'accounts.kind': 'facebook' }
);
- In referenced or normalized data model, If one document is frequetly refering some data in another document, It would create better data model to embed both documents into one.
- If a single document seems to be large, it is better split your data into referential model, the most frequently-accessed portion of the data should go in the collection that the application loads first
```json
// one person and one address
{
_id: "joe",
name: "Joe Bookreader",
address: {
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
}
```
// one person and his multiple address
{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
{
_id: 'some string'
name: "O'Reilly Media",
founded: 1980,
location: "CA",
books: [123456789, 234567890, ...]
}
{
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English"
}
{
_id: 234567890,
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English"
}
{
_id: "oreilly",
name: "O'Reilly Media",
founded: 1980,
location: "CA"
}
{
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher_id: "oreilly"
}
{
_id: 234567890,
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English",
publisher_id: "oreilly"
}