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.
Related
Am i doing this correctly? I know it's super simply, but I am just now getting some DBA experience.
I have an Entity Table that is non static called Emps. The Emps table stores all the Employee personal information like phone numbers and so on. I then have a table called EmployeeOfflineTraining. This Table stores all Employees who are certified in Classroom training like Forklift.
Do i simply put a foreign key inside the EmployeeOfflineTraining table to assign training records to that employee ID?
Emps
(Phone, Agency, Name)
EmployeeOffLineTraining
(GpcScore, Forklift Score, ForklifeCertified, EmpsId)
I would create an indirection table that maps TrainingId to EmployeeOfflineTraining as well. This gives you flexibility in case you need to introduce multiple training types -- you can simply add a row to the Training table rather than having to alter the EmployeeOFflineTraining table.
You may also consider creating an Agency and EmployeeAgency table as well in the same vein.
CREATE TABLE Emps (
empId int unsigned not null auto_increment primary key,
phone varchar(255),
agency varchar(255),
name varchar(255)
);
CREATE TABLE Training (
trainingId int unsigned not null auto_increment primary key,
name varchar(255)
);
CREATE TABLE EmployeeOfflineTraining (
eotId int unsigned not null auto_increment primary key,
empId int unsigned not null,
trainingId int unsigned not null,
score smallint unsigned,
certifiedDate datetime,
foreign key (empId) references Emps(empId),
foreign key (trainingId) references Training(trainingId)
);
Yes.Wikipedia Entry On DB Normilzation What you are looking for is called Databse Normilzation
Employees
EmployeeID PrimaryKey
Phone
EmployeeName
AgencyId
Agencies
AgencyId PrimaryKey
AgencyName
EmployeeOfflineTraining
EMployeeOfflineTrainingId PrimaryKey
EmployeeId ForiegnKey to Employee Table
GpcSocre
ForkliftScore
ForkliftCertified
Edit
As pointed out be Sean Lange The OfflineTraining Table has major problems which are not addressed in this answer.
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 am working on creating a database from an ER diagram however I don't think some of my primary and foreign keys are correct. The tables that I don't think they are correct in is the primary key in section and the FK and PK in enrolled table. I also don't think I am properly enforcing my FK constraints so that I can detect referential integrity violations.
Here is the ER Diagram I am basing my database off of.
Here are the tables that I have made
CREATE TABLE Student
(
StudentId INTEGER,
FName VARCHAR(20),
LName VARCHAR(20),
DOB CHAR(10),
Major VARCHAR(20),
PRIMARY KEY(StudentId)
);
CREATE TABLE Phone
(
sID INTEGER,
Pnumber CHAR(20),
Type CHAR(3),
PRIMARY KEY(Pnumber)
);
CREATE TABLE Class
(
ClassId VARCHAR(6),
Description VARCHAR(30),
NumCredits Integer,
Prereq VARCHAR(20),
PRIMARY KEY(ClassId)
);
CREATE TABLE Section
(
ClassId VARCHAR(6),
SecNo CHAR(10),
Semester CHAR(4),
ClassRoom VARCHAR(6),
TimeOffered VARCHAR(18),
PRIMARY KEY(SecNo),
FOREIGN KEY(ClassId) REFERENCES Class(ClassId)
);
CREATE TABLE Enrolled
(
StudentId INTEGER,
SecNum VARCHAR(40),
ClassId VARCHAR(8),
Semes VARCHAR(6),
GorDD VARCHAR(30)
FOREIGN KEY(ClassId) REFERENCES Section(ClassId),
FOREIGN KEY(StudentId) REFERENCES Student(StudentId)
);
CREATE TABLE Professor
(
EmpId INTEGER,
FName VARCHAR(10),
LName VARCHAR(10),
Dept VARCHAR(2),
QualClass VARCHAR(40),
PRIMARY KEY (EmpId)
);
CREATE TABLE Teaches
(
Class VARCHAR(5),
Section INTEGER,
Semester CHAR(4),
EmpId INTEGER,
FOREIGN KEY (EmpId) REFERENCES Professor(EmpId)
);
CREATE TABLE Qualified
(
EmpId INTEGER,
ClassId VARCHAR(5)
);
Thank you for the help in understanding how to create a DB from an ER diagram.
You really should have a simple, standardized, AUTO_INCREMENT PRIMARY KEY for every table. That makes referring to specific records a lot easier. It's also better to refer to tables by their primary key only when building relationships. String primary keys can be trouble, especially if those strings can change.
Additionally, your arbitrary limitations on string lengths is extremely annoying. Who are you to say people should only have names twenty characters long, or professors can have names only ten long? That's really sloppy. Unless you've got a very good reason, leave it wide open for these sorts of free-form fields, default VARCHAR(255). Hard drives are measured in terabytes today and you'd need to have a hundred million students to fill up your drive with name data.
Otherwise, as a database this is okay. I'd probably discard this schema entirely and rebuild from your entity diagram, a great tool to have by the way, using the conventions of whatever development framework I was using. For example, Ruby on Rails, Django, Drupal, and Tapestry will all have their own ideas on how to name tables.
After a quick look, it looks to me like you would want to have a compound primary key for Section made up of ClassId, SecNo, and Semester assuming those three attributes make up the uniqueness scope for the entity of Section. You could also just have a SectionID that is unique (such as an auto-incrementing int)
For Enrolled, I would make an auto-incremented primary key and have a foreign key that links to the Section table depending on how you solve that entity/table's uniqueness.
Hope this helps. Of course, there are many ways to go about this.
It is usually more useful and more practical to use primary keys specific to the database domain because in real life most entities don't have truly unchanging and unique keys perfectly suited for primary keys.
For example, data entry errors may necessitate the change of a student ID in the database. If you use a property that ends up changing then you'll have to create (effectively) a new student for every change in primary key(StudentId).
The alternative solutions:
Use an automatic key in the database and make the StudentId unique but not primary.
Use a StudentId as the primary key and have it be auto updated every
time it changes in the parent table.
I don't recommend the second option because it is just a workaround the old problem.
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.
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.