问题
I have a class which is part of a school and this class has teachers and students, all of them has name and maybe has phone number , I want to get the full data for the classes but firstly, could you advice me, what is the best for performance and maintaining from the following Dbs :
1st one
"schools":{
"school1":{
"class1":{
"name":"SC1",
"teachers":[{
"name":"T1"
}, {
"name":"T2"
}],
"students":[
{"name":"S1"},
{"name":"S2"}
]
}
}
.
.
.
.
.
.
.
}
and the 2nd
"school":{
"school1":{
"name":"SC1"
},
"school2":{
"name":"SC2"
}
},
"classes": {
"class1": {
"name": "C1"
},
"class2": {
"name": "C2"
}
},
"students": {
"student1": {
"name": "S1",
"phone":"123456789"
},
"student2": {
"name": "S2",
"phone":"123456789"
},
"student3": {
"name": "S3",
"phone":"123456789"
},
"student4": {
"name": "S4",
"phone":"123456789"
}
},
"teachers": {
"student1": {
"name": "T1",
"phone":"123456789"
},
"student2": {
"name": "T2",
"phone":"123456789"
},
"student3": {
"name": "T3",
"phone":"123456789"
},
"student4": {
"name": "T4",
"phone":"123456789"
}
},
"classes_enrollments": {
"class1": {
"teacher1": true,
"teacher3": true,
"student1": true,
"student2": true
},
"class2": {
"teacher2": true,
"teacher4": true,
"student3": true,
"student4": true
},
"class3": {
"teacher1": true,
"teacher2": true,
"student3": true,
"student4": true,
"student1": true,
"student2": true
}
},
"student_friends": {
"student1": {
"student2": true
},
"students2": {
"student1": true,
"student3": true
},
"students3": {
"student2": true
}
},
"teacher_friends": {
"teacher1": {
"teacher2": true
},
"teacher2": {
"teacher1": true,
"teacher3": true
},
"teacher3": {
"teacher2": true
}
}
and for the 2nd way how to get the full data for the class1: in which school and it's name and count of teachers and students and their names and phones
Thank you
回答1:
I would mix those two.
For code simplicity and reading performance of individual class details, the 2nd scheme would indeed be messy. The 1st scheme would be better, but with some improvements.
Keep the teachers
and students
paths at root, just like in the 2nd scheme.
Add teacher_enrollments
and student_enrollments
path at root, to save the ids of the classes that each teacher/student is associated with.
Don't save class teachers and students as arrays inside classes, but use maps instead, similar to what you're saving in the root teachers
and students
path.
That way, when you edit a teacher from the root path, you can also get a list of all their associated classes (the ids) from the enrollments path, and do a multi-path update for these classes, to update the teacher/student details in each associated class.
If you have lots of data, you might want to maintain a separate path for class summaries, so that you can easily show a list of classes, without having to download the data for all included teachers and students (which would be present multiple times in all these classes).
When you delete a class, you would also want to do a multi-path update to delete all associated enrollments. If the total number of students and teachers is not too big, you can just delete the enrollments for ALL teacheres/students. If you have lots of teachers/students, you could keep your (it's actually a lot simpler. You already have the teacher/student IDs in the class info)classes_enrollments
path (but with intermediate teachers
and students
before the ids), so that you can make an update with only the required teacher/student ids.
// How to delete a class in JavaScript.
// For Java, use updateChildren() instead of update(),
// and supply it with a HashMap instead of a plain object.
const classToDelete = { id: 'class1', teachers: ..., students: ..., school: ... };
const updateObject = {
['classes/'+classToDelete.id]: null },
['schools/'+classToDelete.school.id+'/classes/'+classToDelete.id]: null },
};
Object.keys(classToDelete.teachers).forEach(teacherId => {
updateObject['teachers/'+teacherId +'/classes/'+classToDelete.id] = null;
});
Object.keys(classToDelete.students).forEach(studentId=> {
updateObject['students/'+studentId+'/classes/'+classToDelete.id] = null;
});
dbRef.update(updateObject);
Example database structure (slightly different than instructed, but using the same concepts):
"schools": {
"school1": {
"id": "school1",
"name": "The best school",
"classes": {
"class1": {
"id": "class1",
"name": "The best class"
}
}
}
},
"classes": {
"class1": {
"id": "class1",
"name": "The best class",
"teachers": {
"teacher1": {
"id": "teacher1",
"name": "The best teacher",
"phone": "123"
}
},
"students": {
"student1": {
"id": "student1",
"name": "The best student",
"phone": "456"
}
},
"school": {
"id": "school1",
"name": "The best school"
}
}
},
"teachers": {
"teacher1": {
"id": "teacher1",
"name": "The best teacher",
"phone": "123",
"classes": {
"class1": {
"name": "The best class",
"school": {
"id": "school1",
"name": "The best school"
}
}
}
}
},
"students": {
"student1": {
"id": "student1",
"name": "The best student",
"phone": "456",
"classes": {
"class1": {
"name": "The best class",
"school": {
"id": "school1",
"name": "The best school"
}
}
}
}
}
Good luck!
来源:https://stackoverflow.com/questions/58440133/how-to-get-full-data-from-many-to-many-relationship-in-firebase-db-android