我使用了meteor,mongoDB和auto-form。我的数据模型中有很多实体。 学院有一些学生,老师和班级。班级有一些学生和一名教师,每个学生都有一些成绩。
我设计了这个架构:
Schema = {};
Schema.UserProfile = new SimpleSchema({
name: {
type: String,
label: "Name"
},
family: {
type: String,
label: "Family"
},
address: {
type: String,
label: "Address",
optional: true,
max: 1000
},
workAddress: {
type: String,
label: "WorkAddress",
optional: true,
max: 1000
},
phoneNumber: {
type: Number,
label: "Phone Number",
optional: true
},
mobileNumber: {
type: Number,
label: "Phone Number"
},
birthday: {
type: Date,
optional: true
},
gender: {
type: String,
allowedValues: ['Male', 'Female'],
optional: true
},
description: {
type: String,
label: "Description",
optional: true,
max: 1000
}
});
Schema.User = new SimpleSchema({
username: {
type: String,
regEx: /^[a-z0-9A-Z_]{3,15}$/
},
emails: {
type: [Object],
// this must be optional if you also use other login services like facebook,
// but if you use only accounts-password, then it can be required
optional: true
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date,
optional: true
},
profile: {
type: Schema.UserProfile,
optional: true
},
// // Add `roles` to your schema if you use the meteor-roles package.
// // Option 1: Object type
// // If you specify that type as Object, you must also specify the
// // `Roles.GLOBAL_GROUP` group whenever you add a user to a role.
// // Example:
// // Roles.addUsersToRoles(userId, ["admin"], Roles.GLOBAL_GROUP);
// // You can't mix and match adding with and without a group since
// // you will fail validation in some cases.
// roles: {
// type: Object,
// optional: true,
// blackbox: true
// }
// // Option 2: [String] type
// // If you are sure you will never need to use role groups, then
// // you can specify [String] as the type
roles: {
type: [String],
optional: true
}
});
//Meteor.users.attachSchema(Schema.User);
Schema.Grade: {
student: Schema.User,
class: Schema.Class,
gradeValue: value
}
Schema.Class: {
teacher: Schema.User,
students: {
type: [Schema.User]
},
grades: {
type: [Schema.Grade]
}
}
Schema.Academy: {
name: {
label: "academy name",
type: String
},
students: {
type: [Schema.User]
},
teachers: {
type: [Schema.User]
},
classes: {
type: [Schema.Class]
}
}
但我认为这不是最好的,而且会遇到很多重复。
我需要以下查询:
academy classes
academy students
academy teachers
students classes
students grades
student profile
class students
class teacher
class grades
teacher students
teacher classes
teacher profile
答案 0 :(得分:1)
首先要识别实体:student, teacher, class, academy
其次,确定从最大的关系开始的关系:
接下来是关系模式。这里的技巧是最小化数组的使用,因此对于每个1:M的关系,将外键放在M:
_id, name
_id, name, teacherId, academyId
所有外键的索引(teacherId,academyId)。
现在我们没有任何重复,但我们仍然需要处理学生:班级关系。
Grades
集合的示例是教科书3NF,SQL方式。它没有错,这是一个很好的解决方案。 (只需确保在外键上编制索引!)。
或者,在学生文档上你可以有一个对象,每个字段都是classId&每个值都是等级。
另一个选择是在类文档上有一个学生对象,每个字段都是studentId,每个值都是等级。
您如何确定最佳选择是访问模式。如果你有一个学生门户网站,他们可以看到他们的课程和成绩,将它放在学生集合上是更有意义的,偶尔的查询得到一个平均课程将更加昂贵,因为它必须遍历所有学生。对于在类集合中嵌套,反之亦然。