Best technique to implement skill matrix - mysql

Recently I was asked to design a portal where students can upload their technical skills like: HTML, PHP, C++ etc. and college can search the students based on the mandatory and optional skills.
Initially I thought of storing the student and their related skills details using a two columned table where first column represents the student and second column consists of all the skills related to that student separated by comma. For example,
001 HTML,C,C++,JAVA
002 C,JAVA
003 HTML,.NET
...
...
But now I'm facing problems in querying and searching for the student who have relevant skills. I tried a lot but end up with no clue on how this can be achieve.
Any pointers on storing techniques and searching algorithms etc. would be helpful. Help is much appreciated.
Thanks

A simple way to handle this is to have three tables. The first table contains students and includes a unique ID for each student. The second table contains skills and has a unique ID for each skill. The third table is for cross-referencing the first two and has two columns: "Student ID" and "Skill ID".
E.G. Let's say the skill table has an entry for "C" with ID 1, and for "C++" with an ID of 2. We have a student with an ID of 1 who knows both C and C++. We put two entries in cross-reference, the first entry has a student ID of 1 and a skill ID of 1, the second entry has a student ID of 1 and a skill ID of 2.
When you need to find out what skills a student has you just find all the rows in the cross reference table for that student ID. Conversely, if you want to find out what students have a certain skill you just find all the rows with that skill ID.

Related

Need advice for designing university database

Introduction
Currently I'm designing a database structure for my university. I want to store student personal data and staff (non student) data. FYI, the total number of student's records is about 136K, incrementing about 10K each year. On the other hand, staff's records is only about 3K (slow incrementing).
Problem
I argued with my friend about three options below:
Create Person table, staff table and student table. The last two is inherited from Person table.
Create Person_staff table, staff table (inherit from person_staff). Then, same goes to student, create Person_student, and student table (inherited from Person_student).
Create Staff and Student table.
My opinion, option #1 is the best choice. But my friend argued that if we do that (option #1), we will have slow query when we need to retrieve only staff data, because had to join with Person table which is filled with student records (significantly larger than staff records).
Any advice for me? Thanks in advance.
EDIT: FYI, we need to be able to track each person (whether staff or student) who was once a student or staff.

Is there a query for this?

Im making a system for a school and I have this mySQL tables. The names are self explanatory:
student: id name course_id
course: id name
subject: id name
subject_course: id subject_id course_id
grade: id type grade
grade_type: id name
I need to check if every student of a certain course has a grade of type X on every subject that is related with that course.
Let's say grade_type = 'written test'. So I need to check if every student of 1st grade has a grade on the written test on EVERY subject related to first grade (example: math, spanish, history, etc). If yes, I do some stuff. If not, another.
Is there a query that can check that? I was thinking on check student by student but I think is less efficient.
This schema doesn't seem to make sense.
Why would course_id be field on student table? My guess is you need a student_course table to represent a many-to-many relationship between students and courses here.
Also, the grade_type table seems kind of trivial and extra overhead with little value. Could type not just be an enum on grade table?

Design database for 1 to 1 relationship when some columns are applicable only in certain cases

I have a users table which stores the details of two types of users namely students and teachers. There are 10 fields like username, password etc common to both students and teachers. There are no 1 to n relations in case of any data here.
In case of students, I have to store twenty different 1 to 1 data like weight, DOB, Admission No., Parent,Phone number etc.
In case of teachers, I have to store a separate set of twenty 1 to 1 data like email id, affiliation number etc which is not related to students in any way.
What is the best database structure I can use in this scenario from below? If there are better options please provide that too.
One table with 50 columns where 20 columns will have NULL in case of students and 20 columns will have NULL in case of teachers
One table with 30 columns where first 10 columns stores common data and next 20 columns store students details in case of student and teacher's data in case of teacher.
Two tables one with 10 column to store user details. And another table with 20 columns to store students details in case of student and teacher's data in case of teacher.
Three tables one with 10 column to store user details. Another table with 20 columns to store students details and yet another table with 20 columns to store teacher's data
Single Table Inheritance and Class Table Inheritance are both fine. In fact Fowler has recommended STI for agile. And if you use a good ORM like Hibernate, the difference is trivial. If you use PostgreSQL your nulls won't take up any extra space either.
That being said, you should further normalize your tables (parents phone #s should be in a diff table for example). See https://dba.stackexchange.com/questions/12991/ready-to-use-database-models-example/23831#23831 for some help
You have to remember the principles of relational design. All the columns should be dependent on the key fields and only on the key fields.
Its better to have choice 4 tables:
1) For a base person details (columns teachers and students both have).
2) A teacher table for details that pertain to only teachers. This will relate to base person table with a foreign key (just like table 3).
3) A student table for details that pertain to only students.
No extra empty columns and very flexible in the kind of queries (some of which that you are not anticipating) you will be able to do.
the First thing I thought of was a pigs ear relationship, a link entity so that you could have ID, teacherID, studentID to show which teachers teach which students, but then I realised this isn't what you asked for so...
Why not just have a single boolean, true if teacher, false if not?
Look up these two tags: single-table-inheritance class-table-inheritance
These correspond to well known techniques that are like option 1 and option 4. There are situations where one or the other of these is best. The tag wikis (info) and the questions grouped under the tags will give you some additional help.

Mysql tables link with each other

I will create 3 tables in mysql:
Movies: id-name-country
Tv-Series: id-name-country
Artists: id-name-country
Instead of entering country information into these tables seperately, i am planning to create another table:
Countries: id-country
And i will make my first three tables take country data from Countries table. (So that, if the name of one country is misspelled, it will be easy just to correct in one place. Data in other tables will be updated automatically.
Can i do this with "foreign keys"?
Is this the correct approach?
Your approach so far is correct, ONLY IF by "country" in Tv-Series and Artist you mean country ID and NOT a value. And yes you can use foreign keys (country id in tv-series and artist is a foreign key linking to Countries);
Edit:
Side note: looking at your edit I feel obliged to point out that If you are planning to link Movie/TV-Show with artist you need a 4th table to maintain normalization you've got so far.
Edit2:
The usual way to decide whether you need tables is to check what kind of connection 2 tables or values have.
If it's 1 to many (like artist to country of origin), you are fine.
If you have Many to many, like Movie with Artist where 1 artist can be in multiple movies and 1 movie can have multiple artists you need a linking table.
If you have 1 to 1 relation (like customer_ID and passport details in a banking system, where they could be stored separately in customer and Passport tables, but joining them makes more sense because a banks only hold details of 1 valid passport for each customer and 1 passport can only be used by 1 person) you can merge the tables (at the risk of not meeting Normalization 3 criteria)

Database: Tables design/structure

I am new to database structure and design. Currently, I am in the process of creating a course catalog that will match course description according to course name and date. I have sketched one table describing the courses, which include course_code, name and every other relevant information. Then I sketched another table linking those courses to when they will be taught.
I am missing classes that are classified as all_year. Also I am missing a way how to label the courses under a major. Since hypothetically a course can belong to several majors, putting the data from one into the other would force you to duplicate data. Any ideas how I would implement this two things to my tables design? Or suggestion in how to restructure my design. If possible please show me a query to execute in my phpmyadmin DB.
Example of table courses
id serial
course_code text
description text
Example of table course_dates
id serial
course_id serial
year date
semester
Example of table majors
major_id int
course_id int
So a populated database could contain the following:
Table courses
id course_code description
1 INF1000 "Basic programming"
2 INF1001 "More basic programming"
Table course_dates (0 for spring 1 for fall)
id course_id year semester
1 1 2012 0
2 1 2013 1
3 2 2013 1
To link courses to majors - this is a one to many relationship (one course to many majors) - you want to use a linking table that has this type of structure:
table courses_majors
major_id int
course_id int
Remember to index this table as well - its very important. Then you can populate it and have one course even go to many majors and many course to one major (many to many relationship).
Then you can run a join on the tables across this table:
select * from courses left join courses_majors on courses.id = courses_majors.course_id left join majors on courses_majors.majors_id = majors.id
Of course you can add a where clause, etc.
The other way is to create a table of majors:
majors
id int
name varchar
Then add a major_id to your courses table - this will just give you a one to one relationship from courses to majors, but many courses can join a major.
As for Yearly, I would just add a field in the database to account for this, probably a tiny int and just make it 0 or 1.