database query and index - mysql

Given two relations:
Students = (St-Id, Name, Address, CourseNo, Cgpa)
Courses = (CourseN0, CourseName, Credits)
where primary keys are St-Id and CourseNo. CourseNo in Students relation is a foreign key references Courses relation.
Assume the following queries are frequent:
Question: What are the courses (CourseNo and CourseName) studied by each student?
SELECT Students.Name, Courses.CourseName, Course.CourseNO
FROM Students
INNER JOIN Courses
ON Students.CourseNo=Course.CourseNo;
Is that the right query by using join operation?
It's a a primary index because of course number. Can we consider it as rule to say courseNo is a primary index? It's also clustering? What is the difference between clustering and primary index?
Question: What is the Cgpa for each student?
Answer : Select Cgpa and name from students

I agree with simon at rcl, your design only allows one course per student. Try to put an intersection table between student and courses.
Students = (St-Id, Name, Address, Cgpa)
Courses = (CourseN0, CourseName, Credits)
StudentCourse = (St-Id, CourseN0)

If the table has a primary key, then the clustered index is the same as the primary key. If it doesn't have a primary key, InnoDB will create a clustered index on its own. The rules it uses to decide how to do this are described here.
Your syntax is not quite right. To select multiple columns from the table, you separate them with comma, not and. So it should be:
SELECT name, cpga FROM student

Also, if St-id is the primary key of Students then a student can only have one course. You design looks a bit lacking there.

SELECT
name
,cgpa
FROM
students
WHERE
1=1
try this

Related

What is the point of providing a JOIN condition when there are foreign keys?

TL;DR: Why do we have to add ON table1.column = table2.column?
This question asks roughly why do we need to have foreign keys if joining works just fine without them. Here, I'd like to ask the reverse. Given the simplest possible database, like this:
CREATE TABLE class (
class_id INT PRIMARY KEY,
class_name VARCHAR(40)
);
CREATE TABLE student (
student_id INT PRIMARY KEY,
student_name VARCHAR(40),
class_id INT,
FOREIGN KEY(class_id) REFERENCES class(class_id) ON DELETE SET NULL
);
… and a simple join, like this:
SELECT student_id, student_name, class_name
FROM student
JOIN class
ON student.class_id = class.class_id;
… why can't we just omit the ON clause?
SELECT student_id, student_name, class_name
FROM student
JOIN class;
To me, the line FOREIGN KEY(class_id) REFERENCES class(class_id) … in the definition of student already includes all the necessary information for the FROM student JOIN class to have an implicit ON student.class_id = class.class_id condition; but we still have to add it. Why is that?
For this you must consider the JOIN operation. It doesn't check if your two table or collection have relation or not. So the simple join without condition (ON) you will have a big result with all possibilities.
The ON operation filters to get your expected result
Reposting Damien_The_Unbeliever's comment as an answer
you don't have to join on foreign keys;
sometimes multiple foreign keys exist between the same pair of tables.
Also, SQL is a crusty language without many shortcuts for the most common use case.
JOIN condition is an expression which specifies the maching criteria, and it is checked during JOIN process. It can cause a fail only if syntax error occures.
FOREIGN KEY is a rule for data consistency checking subsystem, and it is checked during data change. It will cause a fail if the data state (intermnediate and/or final) does not match the rule.
In other words, there is nothing in common between them, they are completely different and unrelated things.
I feel like I have to reiterate parts of the question. Please, give it a second read - Dima Parzhitsky
Imagine that your offer is accepted. I have tables:
CREATE TABLE users (userid INT PRIMARY KEY);
CREATE TABLE messages (sender INT REFERENCES users (userid),
receiver INT REFERENCES users (userid));
I write SELECT * FROM users JOIN messages.
What reference must be used for joining condition? And justify your assumption...

SQL: delete from joint tables where count condition

I have these tables:
tutors:
email firstname, lastname...
courses:
url tutorid description
reviews:
review courseid author
author in reviews and tutorid in courses is foreign key = tutors.email.
I need to delete all tutors that have 2 or more courses without a description.
I first tried to just select such tutors:
select tutors.email, COUNT(courses.url)
from courses
left join tutors on courses.tutorid = tutors.email
where
description is null group by (tutors.email);
this works fine. However I'm not sure how to delete the tutors with the given emails, considering the tutors.email is a foreign key in other tables.
If you don't delete the records in related tables that contains the foreign key, you will eventually create something called orphaned records, and that is something that goes against the referential integrity rule in general in RDBMS.
It is also possible that the RDBMS will enforce referential integrity, and you wont be able to do that before you delete all the associate records in the other tables first.

DB design - suggestions. Normalize

I'm trying to improve the database design of my web system. Basically I have some doubts about a table that I have where I store the data of all my users, like FirstName, LastName, etc. This table stores the same data for all my different users, on this case for Students, Profesors and two more type of roles. Right now I have it as one single table call it PERSON. There I have all the relations of my foreign keys, even between "Persons" when a Student have a Profesor as Tutor. But I use some colums only when the Person is a Student, fields Enrolled or PaidUp for example and I keep it as null when is other type of role.
Now, my question is what are the cons and pros to divide the table Person, and create subclasses and store only the foreign key where I need it. Should I keep the single table and use "where" to filter my query, or do I normalize the table in several
tables doing a join on Person when I need the general data?
A person is a person and should have its own table. A student or professor is a role played by a person. A person can play many roles. I was a student at my university, then I later taught there.
A student is enrolled in a class, so have an tacit relationship with a professor in that way. You could also track relationships explicitly, as below
Read up on Table Inheritance too
You design should look like this:
PERSON
id
name
dob
...
PERSON_ROLE
person_id references PERSON(id)
type {student, prof, etc}
student_number (nullable)
salary (nullable)
...
PERSON_RELATIONSHIPS
from_person_id references PERSON(id)
to_person_id references PERSON(id)
type {tutorOf, studentOf, ...}
...

good practice in MySQL DB structure

I'm working on a system to manage students attendance in class. I created two tables: student (student_id,name,mail..) and course (course_id, name, lecturer...). now my question is how should i keep record of which students taking which courses?
should i create another table for each course with this structure:
course_id,lecturer,student_1,students_2,student_3...
or maybe there is a better solution for creating this relation?
tx
UPDATE: i should have mentioned that student can take several courses
Since there is a many to many relations between your tables(every student can take many courses,each course can be taken by multiple students) you need an intermediary table which hold the primary key of both table.
coursestudent(course_id,student_id)
with FOREIGN KEYs to the respective tables.
Depends, if a student can have multiple courses and a course belongs to multilple students you want to make a table that contains id, course_id(FOREIGN KEY) and student_id(FOREIGN KEY).
If a student can have only one course, but a course can be followed by multiple students you probably want to add course_id to student as foreign key.
You need two tables,
students (student_id, studentName, student.....)
courses (course_id, student_id, courseName, course....)
Here, student is related to course(s) by student_id along with course_id in courses table.
EDIT:
course_id student_id courseName
c12 s34 DB
c12 s35 DB
c43 s86 OS
c65 s45 PHP
c57 s86 OS
... ... ...
... ... ...
... ... ...

Collection as data type in SQL

I have 2 tables one is students and the other is courses
the key for courses will be ID, however I'm having trouble connecting students with courses.
I need a datatype that will be similar to a list
so I can push an id into the data type or remove the id
also, I need a way to return * from courses if the id exists in the data type
You need to create a junction table StudentCourseAssoc
StudentCourseAssoc
----------------------
studentId
courseId
The columns being foreign keys to students to courses respectively.
That's not how you work with a relational database.
(It's possible to put comma separated values in a varchar field and use to join against a table, but it's slow and complicated to use. I have seen such attempts from time to time, and it quickly falls apart when you want to do anything other than the simplest possible queries.)
Add another table, where you reference a course and a student. Example:
StudentCourses
-------------------
StudenCourseId int autoincrement
StudentId int
CourseId int
(The autoincrement key for the relation table is optional, you can omit it and make the combination of the two foreign keys the key of the table.)
To get the courses for a student you join in the relation table. Example:
select
c.CourseName
from
Courses c
inner join StudentCourses sc on sc.CourseId = c.CourseId
where
sc.StudentId = 42