Designing MySQL database - mysql

I have three tables,
student, studentclass , class
student have sid as primary key, class have cid as primary key.
studentclass ties student and class together and has two columns, sid,cid (no special keys).
Is it possible to get rid of studentclass table and use student and class tables only, without creating duplicate entries in student or in class tables?
(class can have multiple students and student can attend multiple classes)
Thanks.

If the business logic states that, one student can attend multiple classes then it is good to have a linking table, StudentClass.
You can think of this as a Many to Many relationship where one student can attend multiple classes and one class can have multiple students.

The studentclass table is required assuming that students attend more than one class.
If they do not you can simply add a classId field into the students table and get rid of the studentclass table.

Without the explicit columns, and having previously written a college registration system many moons ago, here are some of the tables that I had implemented.
Student - obvious, list of students, primary information, etc
ClassCategory - Generic categories... (ENG)English, (MTH)Math, (SCI)Science, etc, not the specific class level, but the categories
ClassCourse - These are the things that would be found in a syllabus.. ENG-101, MTH-210, etc. This would have the common information describing what the class was about, not who was teaching, credit hours, etc but the material covered, maybe any pre-requisites, basic syllabus for someone to review content.
Semester - List of semesters, such as Winter-2013, Spring-2014, etc.
Facility - List of facility locations that a given class would be taught -- could be buildings, campus, etc
Teacher - list of teachers, there contact information, whatever, regardless of specific classes they might teach.
ClassOffering - Here is where all the courses would be, when offered, etc and would have its own PK ID, but also the ClassCourse, Semester offered, Facility, teacher and specific room and times. You could have the same "ENG-101" course offered 5 times in a day for day and evening classes by different teachers and time slots.
StudentClasses - This is what you are currently at. This would have which student and which specific class OFFERING they enrolled in. Additionally, at this record you could have a drop, withdrawn status, etc and what other settings may be specific, such as credits attempted, earned, final grade, date completion, etc... This table would be the basis of computing GPA for a student.
EACH of these tables would have their own respective "PKID" values and each table SHOULD have their own.
Although this is not an obvious complete database, but it hopefully can lead you to a better consideration of what you may need to consider.

Related

Is it antipattern to create a junction table with more than two foreign keys?

I am designing a database for school management.
Here instead of a single school, there are multiple schools with their own students, classes, teachers and subjects.
Here is the requirements.
• A school can have many classes
• A class can have many sub classes
• Many Students can belong to a section of a class
• Many Teacher can belong to a section of a class
• Many Subjects can belongs to a section of a class
• School wants to manage classes
• School wants to manage sections
• School wants to manage subjects in a section of a class
• School wants to assign a teacher for a subject in a section of a class
• School can assign a student a section of a class
Also, some school can have classes as named One, Two, Three and Some may have First, Second and Third. Also same for sections or sub classes
For entities School and Teacher things are straight forward. Below is my approach for them.
School
--------------
id
name
...
Teacher
--------------
id
school_id
name
But I am facing problem while mapping classes and sections for a school.
I tried to make two other entities classes and sections and give them a foreign key of the school
SchoolClass
-----------------
school_id
class_name
...
SchoolSection
----------------
school_id
section_name
...
For mapping a school's class to all its section I created a junction table, as it will be many to many relationship.
SchoolClassSection
---------------------------------------------------------
school_class_id
school_section_id
But as I mentioned above I also need to add subjects and teachers to a section of the class so tried something like below.
SchoolClassSections
---------------------------------------------------------
school_class_id
school_section_id
subject_id
teacher_id
But now I ended up having four foreign keys in the junction table.
Is there no issues in having more than two foreign keys in a junciton table?
Also, I need to add students too, but I can't now figure it out How to move further for students relation for classes, sections?
One thing I could thing of like below
student
-----------
school_id
school_class_section_id // but if SchoolClassSections can have subject_id and teacher_id too it will become confusing
No, it is not an "antipattern". There are many examples where a junction table might have more than two foreign keys:
A doctor's appointment might have a doctor, a patient, and a clinic.
A retail order might have a customer, a location, and a payment type.
An online subscription might have a customer id, product, payment type, and source.
Those are just some examples from other domains (and they do not even include a date dimension). It is not uncommon for a table to have multiple foreign keys.
I didn't analyze your schema, due to time constaints here.
But there's no problem from either the relational point of view or the SQL point of view with a table or junction table having more than two foreign keys. In fact, that's pretty common.
Some concepts, especially OO concepts, do not fit well with SQL.
SQL has "only":
1:1 relationships (generally this should not be used)
1:many (implement via a link in one table to the other)
many:many (requires a separate 'junction' table)
In each case "1" can degenerate to "0" and "many" can degenerate to "1" or "0". Usually "0" is not represented explicitly but by the absence of rows.
To create schemas:
Think of what "entity" tables to have. (Student, Class, School, etc.)
Create relations, thinking in terms of 1:many and many:many.
Optionally, establish FOREIGN KEYs for the links. (For referential integrity; implicitly creates an INDEX)
Make sure the appropriate columns are INDEXed. (For performance)
Later...
Write the SELECTs, UPDATEs, etc.
Use those queries to decide whether other indexes are needed.
Your question is mainly about the many:many tables.
The basic many:many table has exactly 2 column (links to two other tables)
The basic has two composite indexes (PRIMARY KEY(a,b) and INDEX(b,a))
Sure, make it many:many:many (Not common, but reasonable)
Add columns for attributes about the relations (also not common, but OK)
Add composite indexes for the queries that depend on those attributes (for performance)
More discussion of many:many: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

Should I Increase the number of Tables?

I am trying to model a database, I have designed an ED diagram, do I need to add any more tables to meet the requirements below?
An academic staff may teach many courses
A course must be taught by one or more academic staff
Courses and enrollments must be managed by one or more admin staff
A student can enroll in one or more courses
A grade must correspond to an enrollment
A student may have multiple enrollments in the same course
Here is my current design
You are not satisfying the following rules, notice the "or more":
A course must be taught by one or more academic staff
Courses and enrollments must be managed by one or more admin staff
The following depends on whether you have defined a unique key constraint (which is not visible from the graph)
A student may have multiple enrollments in the same course

Storing Multiple choice answers of a Module Options Form in a Microsoft Access Database

I currently am trying to work out how to create a relational database for a University Module Options form. First you enter your student ID, Name, Surname and select your degree programme e.g. Human Resource Management then choose multiple modules through the form using checkboxes until the total credits for each semester for each programme is chosen.
However in choosing multiple modules and in being a relational database design i am unsure of how to store these multiple answers in the Student Options table as shown below.
I currently have the tables of
Table: Student
Field Names:
Student ID (primary key)
Name
Surname
Table: Programme
Programme (primary key)
Semester 1 Credits (different programmes allow different amount of credits )
Semester 2 Credits (different programmes allow different amount of credits )
Table: Module
Module ID (primary key)
Module Name
Credits
Prerequisite
The last table is one i am struggling with as after the modules are chosen from the form they will be stored in this table and currently have this...
Table: Student Options
Student ID (primary key)
Programme (link to programme table)
However i am unsure what fields to have to store them in without being too cluttered and still having a link to the modules table as shown below which are all stored individually.
Does my modules table need to have a relationship link to the student options table to be a relational database ?
How would i store the multiple modules chosen into the student options form?
Thanks
As for your core problem, I think the database design outlined below should be sufficient:
You should not store both, the modules a student selects and the programme he is enrolled in in the same table. Instead do it like outlined above.
The programme a student is enrolled in should just be a foreign key in the student table, therefore giving you a one-to-many-relation (This is a crucial point though, because this means any one student can only be enrolled in one programme! If your database has to be able to have one student be enrolled in more than one programme, you need a many-to-many-relation there too.).
The modules should be related to a student via a middle table (I called it StudentModule in this case), therefore giving you the desired many-to-many-relation. What you now have to do of course is check via code, if the module isn't already selected by the student (as well as all the other small and big details there are...). But this you would have to do with any database design as far as I know.
As you can see, I also inserted a middle table for the module to programme relation. This is because I assume that one module is eligible for multiple programmes. By relating modules to programmes in this way, you can then check for stuff like "can this student elect this module", ...

How to get rid of this repetition of the same value in a column?

In the miniworld, we have a course called General Science. It has three modules named Module1, Module2, Module3.
(Each module is covered in 2 months, and then there is an exam, and a final exam in the end of the semester - this is not relevant here, but I am just telling for context.)
In each module, roughly 30% of the course content consists of chapters from physics, 30% from biology and 40% from chemistry. So Physics, Biology and Chemistry are kinda parts (please suggest if you have a better word) of the course.
Each Course_Part is taught by different teachers. So teachers are specialized in one or more of those Course_Parts (i.e. Physics, Biology, Chemistry).
There are several courses like General Science.
........................................................
I have two options. Please suggest which one will be a better design:
Make a table/entity type named COURSE_PART ( CoursePartName, Module,
Course, (Chapters) ) and relate it to TEACHER by Teach, a N:M
relationship.
This kinda worries me because there will be a lot of redundant data in the table. Imagine 20 chapters from the same Course_Part in the
same module, i.e. same CoursePartName repeating 20 times in the
CoursePartName column, same module name repeating for 20 times in
the Module column, and same course name repeating for even so many
more times in the Course column. It doesn't appear good to me.
And yes later I will have to make a separate table called CHAPTERS
(because it is a multivalued attribute) and include the primary key
of COURSE_PART in it as foreign key, and it, together with Chapter
attribute will form a composite primary key for CHAPTERS. But I
won't get rid of the kind of repetition I mentioned.
Make an entity named COURSE with two attributes named ID and
CourseName. Make its week entity named COURSE_PART with attributes
named CoursePartName (same repetition in its column), Module (same
repetition in the module column); and relate it to TEACHER by a N:M
Teach relationship?
Is this kind of repetition bad or am I just feeling so? What will be the best way to get rid of this?
A better name for physics/chemistry/biology might be Topic.
Since a topic might be taught as part of multiple modules, it makes sense to have a Course table, a Module table, a Topic table, and a Content table to link modules with topics. Content would have a courseFk column and a topicFk column.
Same with the Teacher table: since each teacher can specialise in multiple topics, you can have a Teaches linking table.
The linking table strategy will prevent repetition when modelling many-to-many relationships.
With Chapter it's a different story: since each chapter belongs to a single topic, your Chapter table should have a topicFk column.

Type-based database design

I want to rate (Very Good, Good, Medium, Bad...) 2 objects: Student and Teacher. Which design solution is better?
Solution 1:
Students(StudentID, Rating,...)
-----------------1--------Good-----
-----------------2--------Bad-----
-----------------3-----Very Good-----
Teachers(TeacherID, Rating,...)
-----------------1-----Very Good-----
-----------------2--------Bad-----
-----------------3--------Bad-----
Solution 2:
Students(StudentID, RatingTypeID,...)
-----------------1----------------2----------
-----------------2----------------1----------
-----------------3----------------3----------
Teachers(TeacherID, RatingTypeID,...)
-----------------1----------------1----------
-----------------2----------------1----------
-----------------3----------------3----------
RatingType(RatingID, RatingDescription,...)
-----------------1-------------Very Good---------
-----------------2---------------Good--------------
-----------------3----------------Bad---------------
If both of them are not good enough, can you give me some suggestions? Thanks!
Solution 2 is the best from those two, but if You want to have multiple votes in the course of your application's life, you should have a table where you identify what is the subject of the vote, and another where you store the votes:
Student:
id
name
class
...
Teacher:
id
name
subject
...
voterType
id
description (student or teacher)
contest:
id
description (ex: 1st Semester 2013)
contestVotes:
id
contestId
voterType (Teacher or Student)
voterId
ratingTypeId
Between the two suggested solutions, I would definitely choose the second one, for the following reasons:
Storing a Rating as a number can come handy in cases where ordering or aggregates are involved, in which cases a string is pretty much useless.
Making the Rating column a Foreign Key to the RatingType.RatingID enforces a constraint, that a Rating can only have values from a very specific set, with very specific meaning. Plus, you could potentially add extra columns to the RatingType table in the future, adding value to your ratings.
As for an improvement suggestion, since you asked, consider implementing this using IS-A relations. A teacher, as well as a student, are apparently both Persons and have common attributes to an extent. I would create a Person superclass table containing the common attributes (i.e. first name, last name, address, phone etc) and then make the primary keys of students and teachers also foreign keys to Persons.
Notice that, a rating is a common attribute too. So it's only natural to appear in the Persons table. Unless of course there are different types of ratings for teachers and students, in which case you would have to implement two different RatingType tables.