RMK*_*147 6 javascript database-design mongoose mongodb node.js
我最近开始使用mongoDB和mongoose作为我的新node.js应用程序.在我努力适应mongoDB/noSQL思维方式(例如非规范化和缺乏外键关系)之前,只使用了关系数据库.我有这个关系数据库设计:
**Users Table**
user_id
username
email
password
**Games Table**
game_id
game_name
**Lobbies Table**
lobby_id
game_id
lobby_name
**Scores Table**
user_id
game_id
score
Run Code Online (Sandbox Code Playgroud)
因此,每个大厅属于一个游戏,多个大厅可以属于同一个游戏.用户对于不同的游戏也有不同的分数.到目前为止,对于我的用户架构,我有以下内容:
var UserSchema = new mongoose.Schema({
username: {
type: String,
index: true,
required: true,
unique: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,如何将关系设计结构化为mongoDB/mongoose模式?谢谢!
编辑1
我现在尝试创建所有模式,但我不知道这是否是正确的方法.
var UserSchema = new mongoose.Schema({
_id: Number,
username: {
type: String,
index: true,
required: true,
unique: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
scores: [{ type: Schema.Types.ObjectId, ref: 'Score' }]
});
var GameSchema = new mongoose.Schema({
_id: Number,
name: String
});
var LobbySchema = new mongoose.Schema({
_id: Number,
_game: { type: Number, ref: 'Game' },
name: String
});
var ScoreSchema = new mongoose.Schema({
_user : { type: Number, ref: 'User' },
_game : { type: Number, ref: 'Game' },
score: Number
});
Run Code Online (Sandbox Code Playgroud)
小智 11
Mongoose的设计方式使您可以相对轻松地对表进行关系建模,并根据ref
您在模式中定义的关系数据填充关系数据.问题是你需要小心填充.如果您填充太多或嵌套您的人口,您将遇到性能瓶颈.
你的做法Edit 1
是正确的大幅但是你通常不希望来填充远程ref
基于一个Number
或设置_id
一个模型的一种Number
,因为蒙戈使用它自己的哈希机制来管理_id
,这通常会是一个ObjectId
有_id
暗示.示例如下所示:
var ScoreSchema = new mongoose.Schema({
user : { type: Schema.Types.ObjectId, ref: 'User' },
game : { type: Schema.Types.ObjectId, ref: 'Game' },
score: Number
});
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因你需要为你的记录保留一个数字id,考虑调用它uid
或不会与mongo/mongoose内部冲突的东西.祝好运!
首先,你在这里找到了一些好点。Mongoose 的美妙之处在于您可以轻松地将模式连接和绑定到单个集合,并在其他集合中引用它们,从而充分利用关系和非关系数据库。
此外,您不会将 _id 作为属性之一,Mongo 会为您添加它。
我已经使用该mongoose.Schema.Types.ObjectId
类型对您的架构进行了一些更改。
var UserSchema = new mongoose.Schema({
username: {
type: String,
index: true,
required: true,
unique: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
scores: [{ type: Schema.Types.ObjectId, ref: 'Score' }]
});
var GameSchema = new mongoose.Schema({
name: String
});
var LobbySchema = new mongoose.Schema({
_game: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Game'
},
name: String
});
var ScoreSchema = new mongoose.Schema({
_user : {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
_game : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Game'
},
score: Number
});
Run Code Online (Sandbox Code Playgroud)
这将允许您查询数据库并填充任何引用的集合和对象。
例如:
ScoreSchema.find({_id:##userIdHere##})
.populate('_user')
.populate('_game')
.exec(function(err, foundScore){
if(err){
res.send(err)
} else {
res.send(foundScore)
}
}
Run Code Online (Sandbox Code Playgroud)
这将填充相关的用户和游戏属性。
两种方式(据我所知)。您存储一个 id(已索引),一旦查询第一个表,您就可以查询第二个表以从中获取信息,因为没有连接。这意味着,如果您从一张表中获取用户 ID,则需要对用户表进行多次查询才能获取用户的数据。
另一种方法是将其全部存储在一个表中,即使它是重复的。例如,如果您需要存储的只是用户的屏幕名称和其他内容,那么只需将其与其他数据一起存储,即使它已经存在于用户表中。我相信其他人会知道更好/不同的方法。