confusion with Relationship of objects - sql

I have one situation given below :
Each student can enrolled into more than one class.
Each class can accommodate more than one student.
which of the following is possible answer :
(1) 1 to N
(2) M to N to 1
(3) M to N
(4) Anything else
if answer is (4) than which other answer is possible ......
any comments appreciable,
thnks in advance, Milan Mendpara

It's M:N.
Look at the problem from both entity's perspective to find the answer.
Each class can have many student entities. So we have 1:M.
Each student can be enrolled in many class. So that's 1:M as well.
In a normalized database you'd have Class and Student defined (minimally) like this:
Class: Id, Name
Student: Id, FirstName, LastName
If you add a foreign key on Class to Student you're only allowing each Class to have a single Student. If you put the foreign key on Student to Class you're only allowing each Student to take one Class at a time. The answer is to use an association table as this is an M:N relationship:
StudentClass: StudentId, ClassId
Hope that helps.

It's number 3.
Multiple students (M) call enroll in multiple classes (N).

The answer is
3 M to N
You need to define a table with fields class_id and student_id to store the relations.
Check out this article about database normalization
http://en.wikipedia.org/wiki/Database_normalization

Related

SQL Recursive Query | multiple Tables Foreign Keys

Scenario
I have a few tables, each table represents an entity of a unique type. For example lets go with:
School, Subject, Class, Teacher. Listed in order as Parent -> Child
Schema
Each table has:
ID: UUID
Name: CHAR VARYING
{parent}_id: UUID<-- example, class would have Subject_id, or Teacher would have Class_id.
The {parent}_id is the foreign id for each table.
Problem
I want to make a query that lists all the teachers of a given school. In order to do this in this Schema, I need to first query Subject by School_id, then Class by subject_id and then finally teacher by class_id.
A recursive functions makes sense to me but all tutorials I find are doing this within a single table and by ids which don't change with each recursion. In my example, each recursion I will need to search for a different ID.
Question
How do you go about doing this? I could make an array of the ids and make an index, increase index and use that to access the id in the array. This however seems like a common query so I believe there might be a more elegant solution.
Note: I am using PostgreSQL
Edit for Comment
I am using PostgreSQL DB and PGAdmin
Why would UUID not work? It has worked up to this point with no problems; even works with cascading delete using foreign keys.
I can show actual schema. However here is a fictitious layout. Quite straight forward I hope.
School
ID
Name
Subject
ID
Name
School_ID
Class
ID
Name
Subject_ID
Teacher
ID
Name
Class_ID
Expected output
Teacher_ID, Teacher_Name, Class_Name, Subject_Name, School_Name
Something like?:
select
Teacher_ID, Teacher_Name, Class_Name, Subject_Name, School_Name
from
school
join
subject
on
school.id = subject.school_id
join
class
on
class.subject_id = subject.id
join
teacher
on
teacher.class_id = class.id

Join query producing 0 results?

I am a bit confused as to how this works, I think I have an idea, but I am not sure. I have two tables:
Student and Classes
The Student table looks like this:
StudentID Name FavoriteClass
The Classes table looks like this:
ClassId ClassName Subject
I have created a relationship between Student.FavoriteClass and Classes.ClassName. However, for the Student table, StudentID is the PK and the ClassId field is the PK for Classes.
I am guessing the reason I can't join these tables is because I am trying to join on fields that aren't keys. If this is the reason, do you guys have recommendations to fix this?
My query looks like this:
SELECT [Classes].[Subject] FROM Classes INNER JOIN Student ON Student.[FavoriteClass].Value = [Classes].[ClassName];
Note: [FavoriteClass].Value is required for Access queries and multi-valued controls.
So if my Student Table had for example:
1 Mark ENG-101
2 Chris CS-103
3 Mary MAT-101
And my Classes Table had like:
1 ENG-101 English
2 CS-103 Computer Science
3 MAT-101 Algebra
4 GS-102 Geography Studies
I want to get the Subject field of Classes where the FavoriteClass of the Student table aligns with the ClassName field of the Classes table.
Please verify that the type of the multi-valued field is really a text type. I guess that it is a number (the ClassId), which would indeed make much more sense. So drop your relationship and (if you will) create a new one between Student.FavoriteClass and Classes.ClassId.
For your query, try this:
SELECT [Student].[Name], [Classes].[Subject]
FROM Classes
INNER JOIN Student ON Student.[FavoriteClass].Value = [Classes].[ClassId];
For more information, I suggest to read this.

SQL table structure relationship feedback

I have 3 tables in my sql. I want to have you guys feedback on how I am building my tables relationship. So I have 4 tables: application_table, teacher_table, student_table and class_table.
Here are several conditions:
A teacher can teach one or many class, but there also teacher teachers 0 class. (1 -> N, teacher -> class_table) relationship. One thing to notice is a teacher may leave the school.
A student can attend many class. One thing to notice is that a student may get expelled or graduated. (1 -> N student-> class)
An application can be used by many student, and a student can use many application. (N -> N relationship)
An application can be used by many teacher, and also a teacher can use many application. (N -> N relationship)
ps. An application may be cut or expired or not used by the school anymore.
application_table
applicationId
applicationName
expiryDate
teacher and class relationship
class_table
classId
classCode
teacherId
Student and class relationship
student_table
studentId
firstName
lastName
classId
application and teacher relationship
application_teacher
applicationId
teacherId
application and student relationship
appliaction_student
applicationId
studentId
IMHO you should first study normalization. One good source is the wikipedia. Your structures are against normalization (ie: Student - Class shouldn't have firstName, lastName ).
A 'school' database is more complex than this but your structures might work for a sandbox learning application, provided you correct the normalization problems.

how to index a one way relation table?

I'm not a DB guy so this may be a trivial question...
Suppose
1) i have a relation table (I think that's what it's called), student_class, which holds a student_id and a class_id, (representing a many-to-many between a student table and a class table)
2) i do various query that results in a student_id (perhaps among other things) and then the results are "LEFT OUTER JOIN"ed to the student_class and LOJed again to the class table to get the associated class information.
3) i do that a lot, but i don't care to find the students from a given class, or any other thing you may think is common to do in the context of students and classes.
4) i have tens of thousands of students but only about 100 classes
5a) 99% of the students are not enrolled in any class (what a great school) and the rest are enrolled in only and only 1 class
5b) alternatively to 5a, on the average, every student is enrolled in about 2 classes
So how many and which of the indices below should i create in the student_class table for this sole purpose, and is the answer different for 5a and 5b?
a. index on student_id
b. index both student_id and class_id
c. index on class_id
I would create one index for each column.
There's not an argument from your question to only add index to class_id. You select values according to student_id and to class_id, so i think it's reasonable to have them both.
Additionally, your index needs don't change if there are more students enrolled in each class.
You make use of the indexes in the same way for both cases.
And for the amount of records you have, the indexes are going to be relatively small.

Dynamic Tables?

I have a database that has different grades per course (i.e. three homeworks for Course 1, two homeworks for Course 2, ... ,Course N with M homeworks). How should I handle this as far as database design goes?
CourseID HW1 HW2 HW3
1 100 99 100
2 100 75 NULL
EDIT
I guess I need to rephrase my question. As of right now, I have two tables, Course and Homework. Homework points to Course through a foreign key. My question is how do I know how many homeworks will be available for each class?
No, this is not a good design. It's an antipattern that I called Metadata Tribbles. You have to keep adding new columns for each homework, and they propagate out of control.
It's an example of repeating groups, which violates the First Normal Form of relational database design.
Instead, you should create one table for Courses, and another table for Homeworks. Each row in Homeworks references a parent row in Courses.
My question is how do I know how many homeworks will be available for each class?
You'd add rows for each homework, then you can count them as follows:
SELECT CourseId, COUNT(*) AS Num_HW_Per_Course
FROM Homeworks
GROUP BY CourseId
Of course this only counts the homeworks after you have populated the table with rows. So you (or the course designers) need to do that.
Decompose the table into three different tables. One holds the courses, the second holds the homeworks, and the third connects them and stores the result.
Course:
CourseID CourseName
1 Foo
Homework:
HomeworkID HomeworkName HomeworkDescription
HW1 Bar ...
Result:
CourseID HomeworkID Result
1 HW1 100