Imagine we have a phpadmin database and we have a table for students and student_music and student_friend student_friend_music. Does this make sense performance wise to have four tables? or do you think we need to have three tables for students students_friends student_music and table for music. How does facebook stores friends relationship in it's database?
Other thing is that I designed the data base for both. I don't know if I see any difference but I think once the users increase one would beat other performance wise?
So my question concerns the performances of querying:
Is this better to have more tables or
Can we have duplicates.
Do you know any good book, tutorial or reference I can study to know about relational data bases in Php my admin and mysql.
Update:
Table Student can have many to many relation with itself.
Table Music has Many to Many with the student as well.
Student id Student_friend Music id STUDENT_MUSIC
A 1 1-3 YT 1 1 3
B 2 2-3 RU 2 2 3
C 3 PI 3 3 1
3 2
So I am using something called Data Mapper in code igniter which causing me a headache but this sounds like a structure I am thinking now.
table suggestions:
table_students (contains students info, etc)
table_music (music pref of studs with student id from table_students)
table_friends (contains student id's from table students and flag value either friend or not friend)
Check out this link for a mysql introduction and the wikipedia article on relational databases. Read about tables, primary and foreign keys. Before worrying about performance you need to address the structure of your database.
Try (One-to-Many:A student can own many pieces of music and have one friend):
CREATE TABLE Student(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
first_name VARCHAR(30),
last_name VARCHAR(30),
friend_id INT)
CREATE TABLE Music(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
music_title VARCHAR(30),
music_student_id INT)
FOREIGN KEY (music_student_id) REFERENCES Student(id)
ON DELETE CASCADE
Or Try (Many-to-Many:Many students can own many pieces of music and have many friends):
CREATE TABLE Student(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
first_name VARCHAR(30),
last_name VARCHAR(30))
FOREIGN KEY (id)
REFERENCES StudentMusic (Student_id)
ON DELETE CASCADE
CREATE TABLE Music(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
music_title VARCHAR(30),
FOREIGN KEY (id)
REFERENCES StudentMusic (Music_id)
ON DELETE CASCADE
CREATE TABLE StudentMusic (
Student_id INT NOT NULL AUTO_INCREMENT,
Music_id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (Student_id,Music_id)
CREATE TABLE Friendships(
student_A_id INT,
student_B_id INT)
PRIMARY KEY (student_A_id,student_B_id)
Handling the data views of the relationships can be shown using a Select statement. In the One-to-Many design finding a Student's music uses the following query:
Select Student.first_name,Student.last_name,Music.music_title
FROM Student
LEFT JOIN Music on (Student.ID=Music.music_student_id)
Part of designing a database is figuring out what relationships you will need to query.
Also look into normalizing databases.
Related
I am working on a data model where I need to store Employee's basic details and his rating of skillsets in MySQL database.
The number of skillsets for each employee is more than 100.
So the information I need to store is as following:
Employee ID, Name , Department , Contact info, Skillset1,Skillset2,Skillset3, ... , Skillset115
Is creating one table with approximately 120 columns is good approach?
If not, what is the best practice to deal with this kind of requirement.
No. You should have a separate table with one row per employee and per skill:
create table employeeSkills (
employeeSkillId int auto_increment primary key,
employeeId int not null,
skill varchar(255),
constraint fk_employeeSkills_employeeid foreign key (employeeId) references employees(employeeId)
);
In fact, you should really have two extra tables. The skills themselves should be stored in a separate table and the above should really be:
create table employeeSkills (
employeeSkillId int auto_increment primary key,
employeeId int not null,
skillId int,
constraint fk_employeeSkills_employeeid foreign key (employeeId) references employees(employeeId),
constraint fk_employeeSkills_skillid foreign key (skillId) references skills(skillId)
);
This type of table is called a "junction table", and is common in any properly constructed data model.
You need to create two tables that would handle the skills and the assigned skill for each employee.
This would give you a proper order in your database and also will extend your options in the future. It'll be better in search, add and assign skills to each employee. It's even more organized and would be able to be expanded easily such as adding skills category and sub-category.
The two tables schema should be something like this :
CREATE TABLE Skills (
Skill_ID INT NOT NULL AUTO_INCREMENT,
Skill_Description VARCHAR(250),
PRIMARY KEY (`Skill_ID`)
);
CREATE TABLE EmpolyeeSkills (
ES_ID INT NOT NULL AUTO_INCREMENT,
Skill_ID INT,
Employee_ID INT,
PRIMARY KEY (`ES_ID`),
CONSTRAINT FK_EMPLOYEEID FOREIGN KEY (Employee_ID) REFERENCES Employees(Employee_ID),
CONSTRAINT FK_SKILLID FOREIGN KEY (Skill_ID) REFERENCES Skills(Skill_ID)
);
The Skills table will assign an ID for each skill, and it'll be in a separate table. This will make you have a unique skills list, there won't be any redundancy. Then, you'll use EmployeeSkills to save the assigned skills on each Employee_ID. Which you can use it later on to join it with other records.
The FOREIGN KEY on Employee_ID and Skill_ID will help you in monitoring the skills between them.
The ES_ID primary key for EmpolyeeSkills will be an additional advantage that can be helpful in the future. For instance, if you want to know the latest skill that has been assigned, then your faster approach will be getting the last ES_ID as it's an AUTO_INCREMENT. This is just one advantage from tons of others.
I'm trying to make 2 "one to many" relationships on the same table, as I have employees managed by TLs supervised by SPVs.
Employees table consists of (ID -PK- , name , hire_date ,,,,,) it's the same data for TL and SPV also
on the ERD I've made it as a one to many on the same table but I've no idea how to make it on SQL (I can't detect what should be refer to who)
I've thought about giving up the one to many relationship idea and add a "type" as 1 if employee and 2 if TL and 3 if SPV but i need to know every TL's employees for example (TL#1 have the employees John , Paul, Smith ,... in his team) and so on
**Note: I'm not sure if it's the right thing to make it as a one to many relationship , if there's any other way I'd really appreciate it :)
sql? just put the same table in the REFERENCES clause.
if you can't do it, do it in a separate SQL sentence.
CREATE TABLE EMPLOYEE (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
spv INTEGER UNSIGNED NULL,
...,
PRIMARY KEY(id)
);
ALTER TABLE employee ADD FOREIGN KEY ( spv ) REFERENCES employee (id) ON DELETE RESTRICT ON UPDATE CASCADE
I would like to know if it is possible to create a table with a column that references values from three other columns. Example is below:
CREATE TABLE Students
(
Id INT PRIMARY KEY AUTO_INCREMENT,
Student_Name VARCHAR(25),
Course_Name VARCHAR(25),
First_Mark VARCHAR(25),
Second_Mark VARCHAR(25),
Third_Mark VARCHAR(25)
);
CREATE TABLE Course
(
Id INT PRIMARY KEY AUTO_INCREMENT,
Student_Course_Name VARCHAR(25),
First_Subject VARCHAR(25), <------|*************************************************
Second_Subject VARCHAR(25), <-----| I want to connect values from these columns... *
Third_Subject VARCHAR(25), <------|*************************************************
FOREIGN KEY (Students_Course_Name) references Students (Course_Name)
);
CREATE TABLE Timetable
(
Id INT PRIMARY KEY AUTO_INCREMENT,
Subject_List VARCHAR(25), <-------| *** ...with this column. In other words, I want mentioned columns to be related.
Date DATETIME DEFAULT NULL,
Avarage_Mark INTEGER,
);
Here is what I want:
http://i.stack.imgur.com/zB0AV.png
Edit 2: Full script. Purpose of this exercise is to create a database that contains students, subjects, and exam timetable.
It's not good relational DB practice to have numbered columns like "First_Subject," etc. unless you can guarantee that the rows will only ever have that many subjects, but no more (and perhaps no less). Even then, I would be hesitant.
Instead you could have a Subject table with subjects and then a Subject-Courses table that linked courses to as many or few subjects as you like. You could then also have Timetable rows that link to Subject rows.
An example schema (I'm sure you can figure out the DDL) given your question would be:
Students (stuID, name)
StudentCourses (scID, couID, stuID, enrollmentDate)
StudentCourseMarks (scID, mark, markDate)
Courses (couID, name)
Subjects (subID, subject)
CourseSubjects (couID, subID)
I'm not really sure how Timetable would fit in. Seems to be more of a derived table, i.e. it should not exist as part of the schema.
I have two tables classroom and computer and currently computer is a variable in the table classroom
CREATE TABLE classroom_tbl
(
room_id INT AUTO_INCREMENT PRIMARY KEY,
teacher_name VARCHAR(30),
subject_name VARCHAR(30),
computer VARCHAR(30)
);
and I want to make it so instead of being a VARCHAR in the classroom table the variable computer calls the computer table
CREATE TABLE computer_tbl
(
computer_id INT AUTO_INCREMENT PRIMARY KEY,
computer_type VARCHAR(30),
computer_status INT
);
Is there any way to do this? I've tried UNION and INNER JOIN but I always get an error that says that my columns are different sizes. Which makes sense because classroom is bigger than computer. Thanks for any help you can give!
I believe you are new to SQL and have some experience in programming. SQL does not have variables like we do have in programming langauages such as C/C++/java. Rather SQL tables relate to each other with relationships such as foreign key relationship. You need to go through SQL tutorials for understanding more about relationships, here is a link to one of those:
http://www.functionx.com/sql/Lesson11.htm
In order to use the JOINS you need to have Primary-foreign key relationship between the two tables. You may have to create your table like this:
CREATE TABLE classroom_tbl
(
room_id INT AUTO_INCREMENT PRIMARY KEY,
teacher_name VARCHAR(30),
subject_name VARCHAR(30),
computer_id INT REFERENCES computer_tbl(computer_id)
);
Since a given classroom can have many computers in it, but a given computer can only be in one classroom at a time, it makes more sense to have classroom as a foreign key on the computer table, rather than vice versa:
CREATE TABLE classroom_tbl
(
room_id INT AUTO_INCREMENT PRIMARY KEY,
teacher_name VARCHAR(30),
subject_name VARCHAR(30)
);
CREATE TABLE computer_tbl
(
computer_id INT AUTO_INCREMENT PRIMARY KEY,
computer_type VARCHAR(30),
computer_status INT,
room_id INT
);
To see which computers are in each room, try a query like:
select r.room_id, r.teacher_name, r.subject_name,
c.computer_id, c.computer_type, c.computer_status
from classroom_tbl r
left join computer_tbl c on r.room_id = c.room_id
If anyone comes across this, what I wanted to do was not possible. You can only reference other columns in other tables or create foriegn keys. Unfortunatly you cannot reference an entire table.
I have two tables: one for areas (like science, sport, education), and another for professions (like scientist, designer, golf player). There is a foreign relationship between the two tables, which works without any problems at the moment.
But now I need another table to put "number of workers", "average age", "years in the company" (this list is possibly different for each profession). What is the best way to do this? Create another table? What would be the parent? Basically, it is a third statement.
CREATE TABLE group (
id smallint(5) unsigned NOT NULL auto_increment,
area varchar(30),
PRIMARY KEY (id)
)
CREATE TABLE job (
ref int(10) unsigned NOT NULL auto_increment,
jobid smallint(5) unsigned NOT NULL,
job varchar(50),
PRIMARY KEY (ref)
)
ALTER TABLE job
ADD CONSTRAINT FK_job
FOREIGN KEY (jobid) REFERENCES group(id)
ON UPDATE CASCADE
ON DELETE CASCADE;
From what I understand I would set up a third table as follows
Table: Employee
First_Name varchar(30)
Last Name varchar(30)
Age (int(3))
Employment Date (DATE)
Active (Yes/No)
JobFK (Points to emprego.PK)
With this kind of setup you can use joins on your tables to calculate how many workers are in the same profession. The average age of those employees, and how long they have been with the company. Given more information about your current tables I could even describe the sql queries for that information.