Database design for Group Supervision - mysql

I am currently having an issue with my database that requires supervisors to monitor a group with students in the group.
Entites: Student, Supervisor and Group
A Student can only be in one group but the group can have many students
A Group can have only one Supervisor but Supervisors can have Many Groups
I hope this Image will explain more:

Here how it is supposed to be according to your data model explained.
As explained, removed StudentID from Groups and added GroupID into Students since Groups can have MANY students but Student can be assigned to only ONE group.
SupervisorID should stay in Groups since Groups can have only ONE Supervisor.

Related

Better way to design Attendance Managment Design

Good evenings. I trying to make simple Attendance Managment Sytem using MySQL. My goal is teacher can mark student attendance in given day and student can see his/her attendance. But i am having problem about design. First, let me explian my system.
Here is my plannig....
System has Student,Teacher and Courses.
A Teacher can teach multiple Course.
A Course can have multiple Teacher.
A Course dividen in Groups, for example 1 Course have group 1 and group 2 in different times.
A Teacher can teach Course in Multiple Groups but a Group can have only one teacher.
Student can have only one group in just one Course.
A Group can have multiple students.
A Group can occur in different time for example Group 1 has lecture in monday and tuesday.
Teacher can mark student attendance in his Course and Group
I have confusion in this system.First,i could not figure out where i should connect attendance table, because i wanted to student can see his attendance day by day so i connected to group_dates and as you can see attendance table have many attributes so it will be affect performance. Second one is should i connect student to course_groups alone or should i connect it both course_groups and courses like in the example?
I am very new to MySQL and design, if you can give advice i will be very appriciated

How to model "participation in container and child"

Considering this ER diagram
we have Students who are admitted to participate in an Exam, and each Exam can be split up into multiple Runs (for example, to split up large groups across multiple rooms or to have two Runs for the same Exam in direct succession).
Is it possible to ensure (via database constraints) that Students participate only in Runs that belong to Exams they are admitted to?
I couldn't find a way on my own and also don't know how to phrase this for an internet search.
You have these tables and columns:
exam: id, name
student: id, name
run: id, exam_id (foreign key to exam.id), when (timestamp), room
You need a new intersection table to keep track of what exam is being taken by which student:
int_exam_to_student: exam_id, student_id - both foreign keys
Now, you can query this to determine what runs a student is allowed to be in:
select run.* from run join int_exam_to_student i on (run.exam_id = i.exam_id) where i.student_id = 123;

how to design: users with different roles see different records

I have a schema design question for my application, hope I can get advices from teachers. This is very alike of Role Based Access Controll, but a bit different in detail.
Spec:
For one company, there are 4 roles: Company (Boss) / Department (Manager) / Team (Leader) / Member (Sales), and there are about 1 million Customers records. Each customer record can be owned by someone, and he could be Boss or Manager or Leader or Sales. If the record's owner is some Sales, then his upper grade (say: his leader / manager / boss) can see this record as well (but others: say the same level of his workmates, cannot see, unless his upper grade manager share the customer to his workmates), but if the record's owner is boss, none except the boss himself can see it.
My Design is like this (I want to improve it to make it more simple and clear):
Table:
departments:
id (P.K. deparment id)
d_name (department name)
p_id (parent department id)
employees
id (P.K. employee id)
e_name (employee name)
employee_roles
id (P.K.)
e_id (employee id)
d_id (department id)
customers
id (P.K. customer id)
c_name (customer name)
c_phone (customer phone)
permissions
id (P.K.)
c_id (customer id)
e_id (owner employee id)
d_id (this customer belongs to which deparment)
share_to (this customer share to other's id)
P.S.: each employee can have multi roles, for example, employee A can be the manager of department_I and meanwhile he can also be one sales of deparment_II >> Team_X.
So, when an employee login to application, by querying from employee_roles table, we can get all of the department ids and sub department ids, and save them into an array.
Then I can use this array to query from permissions table and join it with customers table to get all the customers this employee should see. The SQL might look like this:
SELECT * FROM customers AS a INNER JOIN permissions AS b ON a.id =
b.c_id AND (b.d_id IN ${DEP_ARRAY} OR e_id = ${LOGIN_EMPLOYEE_ID} OR
share_to = ${LOGIN_EMPLOYEE_ID})
I don't really like the above SQL, especially the "IN" clause, since I am afraid it will slow down the query, since there are about 1 million records or even more in the customer table; and, there will be as many records as the customers table in the permissions table, the INNER JOIN might be very slow too. (So what I care about is the performance like everyone :))
To my best knowledge, this is the best design I can work out, could you teachers please help to give me some advice on this question? If you need anything more info, please let me know.
Any advice would be appreciated!
Thanks a million in advance!!
Do not use an array, use a table, ie the value of a select statement. And stop worrying about performance until you know more basics about thinking in terms of tables and queries.
The point of the relational model is that if you structure your data as tables then you can looplessly describe the output table and the DBMS figures out how to calculate it. See this. Do not think about "joining"; think about describing the result. Whatever the DBMS ends up doing is its business not yours. Only after you become knowledgeable about variations in descriptions and options for descriptions will you have basic knowledge to learn about performance.

MYSQL - Querying averages of ratings for multiple users in a single query

I am building a site one aspect of which involves teachers and rating teachers. Ratings are made by students, and when students are looking for teachers, among the criteria I'd like for them to be able to filter the teachers by include their average ratings.
Each rating by each student of each teacher puts the number of stars they rate the teacher into the database. I already have a query that can calculate the average stars for each teacher
SELECT AVG(star) AS Average FROM rating_table WHERE type = 'Member_review'
AND teacher_id = id_number
with id_number obviously being the user_id of the teacher.
When people are on the search page for all teachers, I'd love for them to be able to filter the teachers by rating, among other criteria. I can put this query in a foreach loop and have it run down each and every teacher id, but I suspect this will be a huge drag on the server - is there a way for me to put a string of comma-seperated ids into the query and have it find the average rating for each one? I did try this query and it did not work
SELECT AVG(star) AS Average FROM rating_table WHERE type = 'Member_review'
AND teacher_id IN(1,2,3, etc...)
Is there a way in which i can get the query to take the average for each teacher user_id and have it out put something like this?
Average Teacher ID
3.5 6
4.6 2
Yes. This is a basic aggregation query:
SELECT AVG(star) AS Average, teacher_id
FROM rating_table
WHERE type = 'Member_review' and
teacher_id IN(1,2,3, etc...)
group by teacher_id

Dealing with a curriculum database

Okay, I have 3 tables:
Students
Offered_subjects
Enrollees_list
Students will contain all the information of the students of the school
Offered_subjects will contain all the subjects offered by the school
Enrollees_list will contain all information about what subject a students is enrolled in and will also contain remarks for that subject (pass or fail).
Now, the subjects in offered_subjects contain courses that have prerequisites (ie. before qualifying for MySQL101, the student mas have a passing remark in DBMS101)
The categories of prerequisites are:
Academic Year
Semester
Subject
Note that not all the subjects listed in offered_subjects have all the categories for its prerequisite. Some require to finish a certain subject, some require that the student must be in a certain academic year (ie, 3rd year), and some have all three.
What's required for the program is to display all the students that are qualified for a selected subject.
Let's say: MySQL101 has prerequisite of 2nd year, 2nd sem, DBMS101
I need to list all the students that are on their 2nd year, 2nd sem, and have a passing remark in DBMS101.
This would be easy if all the subjects have same categories for its prerequisites where I can put the same queries in the where clause, but my problem is that, again, not all the subjects listed in offered_subjects have all the categories for its prerequisite.
I'm new to MySQL and it's kind of confusing to me at the moment.
How do I do it?
I'm guessing you have the following columns on the Offered_subjects table:
Req_year
Req_semester
Req_subject
If one of your subjects don't have values on this column, you can ignore this check for this column. Something like:
Select ... where (Subject.req_year is null OR Student.year >= Subject.req_year) ...
This way, required year will not be taken into account if it's null.
(note: I'm not completely sure of syntax right now, but that's the idea).