I am planning a database that will record school attendance for students everyday.
The problem is that i cant predict the total numbers of student in a class and also the days will increase steadily, so i am struggling with the MySQL db part.
Should i use the students name as columns and each date as rows? I know that using this approach will force me to alter the table's columns every time i add or remove a student from the class. e.g.
day student1 student2 student3 studentN
---- -------- -------- -------- --------
1 x x x
Have anyone worked on similar problem or have any suggestion?
The "proper" way to accomplish this using what is called a "normalized" database would be to have a students table and an attendance table
students
--------
id
name
attendance
----------
id
student_id
day
The student_id in the attendance table is just a reference to the unique integer id that each student has in the students table.
Now you can add more student data later, such as address, phone, email, etc and usually split name into first and last name fields. It allows you to update a student name without messing up the attendance data.
Imagine if you store a record for John Smith and later find out his name is spelled Jon instead of John. You would have to update all the individual records that contain his name. Or what about the situation where two students have the same name? That will happen. Using a separate students table with a unique id field will allow for you to encounter these situations without a major reorganization of your data or logic.
Related
I am having a problem while setting my database.
The context: I have a company table that can have 0, 1 or multiples jobs. Jobs have its own table. I will need to join both table.
How can I "say" that a company has this, this and this job?
The only way I found is by creating a "job" value in the meta_key entry (of the company table) and declared the jobs in the meta_value entry but it seams not good (and will create difficulty to retrieve the jobs while joining).
You are describing a many to many relation. It works like this
company table
-------------
id
name
other columns
jobs table
----------
id
name
other columns
company_jobs table
------------------
company_id
job_id
Ok, I am new to SQL, so this must sound stupid. Sorry for that.
I have two tables + one junction table (many to many schema) = total of three tables.
First table
students: student_id (PRIMARY) | name | email | password |...
Second table
topics: topic_id (PRIMARY) | topic_name | subject |...
Third table (junction)
jnct_students_topics: id (PRIMARY) | student_id_FK | topic_id_FK | done (boolean) | notes
So how the web app would work?
Second table (topics) is pre-filled with all the topics students need to study.
First table (students) will be filled whenever a new student register for the service.
Junction table (jnct_students_topics) will also be filled when student registers, but (HERE COMES THE QUESTION) I need to know how to insert all topics ids + this student id in topic_id_FK and student_id_FK columns.
Because when a student registers, system will create a list for him/her with all topics to study and a checkbox for each one. After student finishs with topic studying, he/she will check the box and the boolean done column will become true for this topic.
I learned from [this question] (Copy from one column to another (different tables same database) mysql) that, to populate a table column with values from another table column, I could go:
INSERT INTO jnct_students_topics (topic_id_FK)
SELECT topic_id
FROM topics
but I need to build the statement so at the same time the student_id (related to the student that is registering) is inserted (column student_id_FK) in all rows that are being created.
Tired of reading? Well, I don't blame you. Nor english or SQL are native languages of mine... :)
By the way, If you think that this schema is not the best, please, I would appreciate some advice.
Thanks!
I know it's possible to have n amount of columns, but is it proper mysql "coding standard"?
Here is what I'm doing:
I am a table student which includes all the students info including testScores:
student
-------
studId
name
age
gender
testId
Instead of putting each individual test answer within the student table, I made a separate table called testAnswers that will hold each students test results:
testAnswers
-----------
testId
ques1
ques2
.
.
.
quesN
Each entry in the testAnswers table corresponds to a specific student in the table student.
Of course, there will be an admin that will be able to add questions and remove questions as each year the test questions may change. So, if the admin were to remove an answer, than that means one of the columns would be removed.
Just to reiterate myself, I know this is possible to edit and remove columns in a table in mysql, but is good "coding standard"?
The answer is a simple and clear: No. That's just not how you should do it except for very few corner cases.
The usual way to approach this is to normalize your database. Normalization follows a standard procedure that (among other things) avoids having a table with columns names ques1, ques2, ques3 ....
This process will lead you to a database with three tables:
students - id, name, and other stuff that applies to one student each
questions - id and question text for each question
answers - this is a N:M relation between students: student_id, question_id, answer_value
Use two tables!
What you are describing is a one to many relationship as there can be one student to many test scores. You would need to have some id as a foreign key to the student_id and put this id in the testAnswers table. You can then set constraints, which tell the database how to handle removal of data.
As one commenter has mentioned, using one table would result in breaking 1nf or first normal form which basically says that you cannot have multiple values for a single column given a particular record - You can't have multiple test scores for the same user in a given table, instead break the data up into two tables.
...of course 2 tables, also could use 3, just remember to insert a studId column also in the testAnswers table (with REFERENCE to the student table) and an INNER JOIN testAnswers ON student.studId=testAnswers.studId at the SELECT query (to read the data).
Is it possible to have the ID of the next generated row (across 2 tables) be unique?
I have 4 tables:
1 for teachers
1 for students
1 for projects
1 for relations
The relations table has 3 foreign keys.
One refers to teachers IDs, one to students IDs and the other to projects IDs
Since a project can be related to teachers but also students at the same time, how do I make sure that a new created teacher or student won't have an ID already used by the other type of account?
If I can do that, then the relations table would have only 3 columns:
ID, project_ID and related_to(ID)
If not, I would have to add a 4th row indicating the type of account that it relates to (student or teacher).
Thanks for your help!
Regarding the difference between account types:
I have to translate this exact same situation to another project of mine in which the first two tables are completely different. That's why I don't bother to merge the students and teachers tables here.
You do not need to have unique values between the student and teacher tables because the relation table has separate fields for each relationship, so there is no conflict.
However, this is not the right way to do things. You need two relation tables, teacher_project and student_project. Alternatively, depending on the unique data that's different between teachers and students, you could have a single person table and a single relationship, which is probably closer to the real world anyway.
I think you can identify the teachers begin with 1 ,incremental 2; the students begin with 2 ,incremental 2.By this way,odd number refers to teacher while even number refers to student.No conflict will happen.
I am not really experienced with databases but I have a little problem. I am trying to create a database that stores the courses being taken by students and lecturers so I created three tables. In the lecturer and student tables, the field courses represent a comma separated list of the courses taken by either the lecturer or the student.
Something like this:
Lecturer - Courses - "1,2"
Student - Courses - "1,2,3"
Courses - 1 - "Bio"
The problem however is that when I want to show a list of student based on their courses, I have to search all the students and the courses and search again to check whether the csv list has the specified course (which seems a bit redundant). Is there another way I can achieve this goal, say by relating/referencing the indexes or something? Thanks
Create two new tables:
student_courses(int student_id, int course_id)
lecturer_courses(int lecturer_id, int course_id)
You can now create individual rows for each course a student is taking and each course a lecturer is teaching, assuming that you want to track delivery of a course separate from taking the course. You can then write queries against those tables using course id when you want to do course related analysis.
the field courses represent a comma separated list of the courses taken by either the lecturer or the student
A field that contains a csv list is breaking First Normal Form (1NF) and has all sorts of problems, including performance. Breaking out this field into a separate Junction Table {StudentID, CourseID} is what you should do.
Instead of storing a text like "1,2,3", store several rows:
1 row for every student in a table named "students"
1 row for every course in a table named "courses"
Then create another table named "student_in_course" which has 1 row for every combination.
Then do the same for "lecturer_in_course".