Multi-class, interlinked school timetable as a MySQL database - php

I've looked around for a bit now at other suggestions relating to this, but nothing I've seen has quite suited my needs, so here goes!
What I have is a multi-class (Australian secondary school; Years 7-12), multi-day (Mon-Fri) school timetable. What I now want to build is a MySQL database with the following information to be deployed on an account driven website.
Subjects:
Running time (as "Period 1 on Wednesday", "Period 2 on Friday", etc. -- multiple values in this column) Instructor (linked to separate database of all teachers) -- This would additionally need to change (temporarily) if a teacher was sick and replaced; perhaps a "replacementinstructor" column to be ignorned when NULL. Location (different, but specifically allocated, rooms on different days) -- As above, change temporarily when room altered.Other obviousnesses: Course name ("Year 7 Health"), Unique ID (Something like "7.HEALTH", rather than just auto-incrementing INT.), etc.
Teachers:
First name, last name Courses they take Contact infoOther obviousnesses: Unique ID (Auto-incrementing INT), Username (fname.lname), Password for their account, etc.
Students:
First name, last name Courses they attend (stored as an individual list for each student) Year level / Form (Year 7, Year 11, etc.)Basic personal info (Home suburb, email, etc.)More obviousnesses: Unique ID (same setup as teachers), Username (same as teachers), password, etc.
Any insight as to how I might design such a data structure would be greatly appreciated, I'm more of a UI fanatic than a MySQL thinker ;-D
Thanks in advance.

I can think of the following tables to use in MySQL:
students
Student information
id (auto_increment)
firstname
lastname
username
password
student_id (I had a student ID but I can't remember if I was given this in yr 7 or yr 10)
year
email
contact_phone
street
suburb
state (ENUM - ACT,NSW,WA,SA,TAS,VIC,NT,QLD)
teachers
Teacher information
id (auto_increment)
firstname
lastname
title (Dr, Mrs, etc)
username
password
email
contact_phone
street
suburb
state (ENUM - ACT,NSW,WA,SA,TAS,VIC,NT,QLD)
subjects
All the different subjects
id (auto_increment)
subject
subject_code (eg 7.HEALTH)
year
locations
Various locations around the school
id (auto_increment)
location (eg BLOCK A, ROOM 2, MUSIC ROOM)
subject_teachers
What subjects each teacher teaches
id (auto_increment)
subject_id
teacher_id
subject_students
Which subjects each student takes
id (auto_increment)
subject_id
student_id
subject_timetable
Main Timetable
id (auto_increment)
subject_id
location_id
teacher_id
alt_teacher_id (eg substitute teacher)
duration
period (number 1-however many periods in a day. 6 if I remember correctly)
week (number 1-2 or even perhaps 1-52)
weekday (number 1-5)
notes (as #Oswald suggested you could add additional notes for when things change)
The notes could be collated and then displayed as footnotes on the timetable.

You will obviously need a table for Subjects, a table for Students and a table for Teachers.
Read up on database normalization. This will tell you (amongst other things):
Do not put the running time into the Subject table as a comma separated list. Instead use a table for the running time and use a foreign key to map entries from that table to Subjects table.
Same goes for mapping teacher to courses.
Same goes for mapping students to courses.
That Running Time table would also be suitable for holding the location of a course during a specific running time.
Additionally, if you record temporary changes in the database, you are dependent on people changing the relevant information at a specific time. To get around this, you might want to consider a table Lessons, where you record
Running time
Week number
Course
Instructor
Location
Other fields that might be specific to that particular lesson.
This will allow you to schedule changes in advance (Mr. McCachney is sick for the next two weeks, Room 101 is closed for redecoration for a month, etc.)

Related

mysql db normalization help required

please forgive me as Ive been confused and I need your help in normalization of this next mysql database (will work on it along with php). If this is not allowed to post it then ignore :)
I've a need to record large number students to visit a library in order to document it and create analysis and reports later on.
These visits will hold lots of data and criteria for each student single visit, and it will be filled by different supervisor people because the student will visit more than one section.
Hence, there will be some limitations for entry and disallowing certain parts of the form to be accessed by certain users...etc.
My plan is to have a single form with some initial student information and select boxes, radio, checkboxes, and notes as free text, for each visit, as i mentioned, using php as frontend
This is what i have in mind, 2 main tables + other smaller tables to hold the select boxes data as foreign keys.
TABLE1: STUDENTS
student_id
student_number
student_name
student_gender
student_grade
student dateofbirth
student age
TABLE2: VISITS
studnet_id (referring and pulling student info from TABLE1)
date_of_visit
have_did_this_during_the_visit (DropDown)
psychological_reaction (checkboxes)
5 was_wearing_well (yes not selectbox)
And so on, more than 50 criteria to measure for each visit
This way, will have finally 2 forms, one to add student, and one to deal with visits...
Although, visits form/page will be big.. and here comes my question, is this ok? these data of visits table can exceed 40 or 50 fields or do you guys advise different approach?
Thanks for your help in advanced
Have_did_this_during_the_visit (DropDown).
for this you need one table this table will have pk anf fk on visits table's primary key
psychological_reaction (checkboxes) 5 was_wearing_well (yes not selectbox)
for this you need one table this table will have pk anf fk on visits table's primary key
TABLE2: VISITS
visit_id
studnet_id (referring and pulling student info from TABLE1)
date_of_visit
have_did_this_during_the_visit (DropDown)
psychological_reaction (checkboxes) 5 was_wearing_well (yes not selectbox)
have_did_this_during_the_visit
id
visit_id
you DropDown vaues
psychological_reaction
id
visit_id
you checkboxes vaues

Managing a rankings list with MySQL

For a sports club I am in, I want to manage a rankings list with MySQL on the website.
We have a tournament system where players can participate (or not) once a week and get points. Those points are somehow processed and a rankings list should be created on the website.
I am not so experienced with MySQL so I want to know if the system I thought of is good or another approach would be better.
I thought of having two tables:
players
-------
ID (unique primary key)
Name
Surname
+other arbitrary stuff
tournaments
-----------
ID (unique primary key)
Date
player (secondary key, points to player ID)
+ columns for results of that player in this particular tournament
on the website I would then query the tournaments table, sort for ID and Player and process the results to compute a rankings list.
Is this a good approach or is there a better, more convenient way to do this?
You may find later that it would be more convenient to have one more table.
I would change your tournament table to something more like:
tournaments
-----------
ID (unique primary key)
Date
~Location
~+Other stuff about the tournament as a whole
And then add a table:
results
-----------
player_id (points to player ID)
tournament_id (points to tournament ID)
+results
The reasoning is because it will make it easier to filter on a single tournament, and many players could share the same tournament info without duplicating the results on each player.

Voting system using PHP+MySql?

We have to make a ballot system that makes users vote for various candidates on different positions. There's a login for voters. How do you store a vote of one voter and then get that vote added to the previous votes? The only possible way is to store every vote on a database right? But what would the structure of the database look like? And how do you count it?
edit:
The voting system doesnt only have one group of candidates to vote. It has mayor, vice-mayor, senator, etc. There are too many. that's why I'm confused. If only it was just a voting system of a president, it would be easier. So if I have a table for the voter, with a column of his/her voted candidate, it's not possible since the voter votes for many candidates.
A better way would be to have a different table to store Votes. And that table will have two attributes (VoterId, CandidateId)
And you can fetch the Vote Count if you are allowing multiple votes from this table..
But it would be better to make VoterId a Primary key in this table.. To avoid multiple voting
CandidateType: - (TypeId(PK), typeName, maxVotePerVoterForThisType)
Voter Table: - (voterId(PK), voterName, otherInfo)
Candidate Table: - (candidateId(PK), candidateName, constituency,
otherInfo, TypeId(FK))
Votes:- (voterId(PK, FK), TypeId(PK, FK), candidateId(FK))
*EDIT:- Schema edited with changed requirement in original post
*EDIT: - Added a field in CandidateType table to allow multiple votes.(E.g.: Now a voter can vote for 10 Senators, if maxVotePerVoter for this type is set to 10..)
You should e store each candidate in a table, positions in another table then make relations based on ID, the voting system is relatively simple:
database:
id, position_id, candidate_id, votes
then PHP
$query = "UPDATE `votes` SET `votes`=`votes`+1 WHERE `position_id`=1 AND candidate_id=1"; // adds 1 vote where position_id is 1 and candidate_id is 1
These 3 tables are required for your accounts (the voters) and candidates.
Account: Id (PK), Name, Password
Candidates: Id (PK), Name
Votes: AccountId (PK), CandidateId (PK)
Insert a row into votes when a vote is cast. This prevents duplicate voting due to the PK's.
I simple language i can say you are storing voting users in a table called users and you can use a field vaotecount (int) type initilize with zero and track their ip and vote for topic id on which they have voted for and when they vote you can check with IP and topic_id that they are not voting twice and if they passed you can increment the vaotecount field by one
and while you are counting for votes count the users with topic id for which you counting votes. Simple :D
From the explanation of problem, I can suggest you the following database structure:
tlbUserVote:
UserID(PK) | UserName | Vote | CandidateId(FK)
tlbCandidate:
CandidateId(PK) | CandidateName | TotalVotes
By this structure you can add the current votes with previous ones (by taking previous votes first and adding it to the current).
Total votes of the candidates will get updated, too.

How can I store dates/attendance?

I'm looking for for an opinion.
I have a list of people and will need to store when they are present at a location so those in charge can check them off a list. I'm not 100% sure how long the dates will be needed but I'm assuming they may need to look at previous attendance lists.
My first instinct is to have a column for each date but that could result in many many columns. I could just store a list of dates next to each person:
"01/01/2012,01/15/2012,02/18/2012..."
that could result in a very long entry. It seems like neither is a good option.
If anyone has a suggestion or guidance on an approach please let me know. Thanks.
A complex, but also very clean approach would be
Table "persons":
id
name
Table "dates":
id
location
date
... whatever info the "dates" table needs
Table "attendances":
date_id (link to an entry in the "dates" table)
person_id (link to an entry in the "persons" table)
attended (yes/no)
Then fill the database with the appropriate dates, and fill the "attendances" table according to which persons need to be present at each date.
This is, as said, complex to implement, but it's incredibly flexible - you can have any number of dates and attendees; you can excuse people from attending a specific date programmatically; you can add people to groups...
Link tables.
One table of people
ID
Name
One table of classes
ID
Name
One table linking person to class to date.
ID
personID
classID
cDate
So all you would need to do to determine which students were preset on a certain date in a certain class:
SELECT *
FROM people p
LEFT JOIN peopletoclass ptc ON p.id = ptc.personid
LEFT join class c ON c.id = ptc.classid
WHERE ptc.cDate = '2011-11-07' AND c.id = '1';
Above (for example) would get all people in class id 1 on November 7th 2011.
Create a table "attendance" consisting of a person_id field and a date_present field. You can't store this into columns or a long list using a string ;-).
Than you can use queries where you join the table Person with Attendance.
Your first instinct would result in a horrible table design. What you should have is a seperate table that stores the users/locations/dates tuples
e.g.
userID locationID date
1 party 1/1/2011 00:00:00
1 bathroom 1/1/2011 00:05:00
1 party 1/1/2011 00:15:00
would show that user #1 was at a New Year's Eve party, then went to pray before the porcelain altar at 12:05am, then returned to the party 10 minutes later.

How to simplify the following tables and optimize?

Now i have a table with the following fields
id
country
hdate
religions
season
description
link
rate
and i store the data within this table , my sample data will be
1 Afghanistan 2008-01-19 Islamic Winter Ashura ashura 2
2 Afghanistan 2008-03-20 Islamic Winter Mouloud (Birth of the Prophet) mouloud 4
3 Afghanistan 2008-01-01 Common Winter New Year Day new-year 5
4 Albania 2008-04-28 Christian Spring Orthodox Easter Monday easter-monday 4
5 Albania 2008-01-01 Common Winter New Year Day new-year 5
here you can look there is data redundancy and so i've decided to break up the tables and bring some common sense.
I've created a draft but i couldn't finalize what could i do to bring a best data structure.
I decided to bring all countries in one table
and all the holidays data into one table (id, holiday, celebrated_by, religions season link rate) the celebrated_by stores the id of the countries seperated by comma
and the holiday_dates for storing the dates of the holiday.
(holiday_id, date, year) date stores the complete date and the year stores only the year as 2009,2008 etc..
Now i want to list all the holidays of a particular country , list the countries which celebrates the same holiday (when a holiday is listed) etc..
Please suggest me whether this structure is enough or is there any flaws or any changes to be made.
help me
You should have two (or three) tables. one for countries and one for holidays for sure. I would suggest even adding a third for religion, if more than 1 religion share the same holiday. The latter can have a foreign key that links it to the countries table
countries
================
country_id (auto increment)
name
religion
============
religion_id (auto increment)
name
holidays
===============
holiday_id (auto increment)
date
season
description
link
rate
country_id (FK)
religion_id (FK)
Let me know if you need a hand with the joins to query.
if celebrated_by links with the country table's unique key, then it is good, u can easily handle this. But redundany would be there in holiday table
If not then u could either create one or can create another table which links b/w country and holiday (country_id, holiday_id) fields would be enough to sort out queries and reduce redundancy
the proposed structure is fine except that you shouldn't use comma-separated list of ids for linkage. Make 'celebrated_by' a separate table with fields country_id, holiday_id
Theoretically you might want to replace direct references to 'religion' or 'season' with reference tables (like pocketfullofcheese suggested), but I doubt this will be of any practical benefit.

Categories