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.
Related
I have three tables: property, person, and company. One property can only belong to either a person or a company. A person or a company can have more than one property.
My current database design is to include two foreign keys - person_id and company_id in property table, always with one of them null and the other not null. I'm just wondering is there any better way to design the database in this scenario?
CREATE TABLE person(
person_id int NOT NULL PRIMARY KEY,
name varchar(255)
);
CREATE TABLE company(
company_id int NOT NULL PRIMARY KEY,
name varchar(255)
);
CREATE TABLE property(
property_id int NOT NULL PRIMARY KEY,
name varchar(255),
person_id REFERENCES person,
company_id REFERENCES company
);
Create additional table CHECK constraint:
CREATE TABLE property(
property_id int NOT NULL PRIMARY KEY,
name varchar(255),
person_id REFERENCES person,
company_id REFERENCES company,
CHECK (person_id IS NULL + company_id IS NULL = 1)
);
This will forbid wrong values (both NULL or both NOT NULL).
PS. Two references presence is legal and safe itself.
I have two tables tb_schools(school_id,school_name), tb_programms(pid,p_name,school_id)
If suppose multiple schools offer the same program then how can I design the DB.
I mean can I pass the list of school_ids like[sc1,sc2,sc3] in school_id of tb_programms.
note: I can't add multiple rows for a single program.
If multiple schools offer the same program you need to design your schema differently. The canonical solution would be to have a table for schools, a table for programs, and a mapping table for the programs held at each school. E.g.:
CREATE TABLE tb_schools (
school_id INT AUTO_INCREMENT PRIMARY KEY,
school_name VARCHAR(30) NOT NULL
);
CREATE TABLE tb_programs (
pid INT AUTO_INCREMENT PRIMARY KEY,
p_name VARCHAR(30) NOT NULL
);
CREATE TABLE tb_school_programs
sid INT NOT NULL,
pid INT NOT NULL,
PRIMARY KEY (sid, pid),
FOREIGN KEY (sid) REFERENCES school(school_id),
FOREIGN KEY (pid) REFERENCES programs(pid)
);
I am currently working at a construction management software and I stepped into a problem (described below) when designing the schema for my database which contains four tables, for now, i.e employee, address, user and license.
The tables that created the confusion are employee and address; code provided down below.
In order to maintain the Physical integrity of my data, I did not store anything lexically derived from address, such as Address1, Address2, City, State, County etc in the table employee; since I subjectively considered that it would be better for attributes that do not uniquely identify a specific employee to make part of another table. Now my question arises:
Is it a good choice to use a GUID as the primary key for the address table?
If yes, is there any possibility that it may be a factor which prevents fast querying?
The reason why I have chosen to use a GUID as PK-indexing is that I was left with no options. EmployeeId from address does not offer me a solution since I can not have a field being PK as well as FK: see this.
CREATE TABLE employee(
employeeId INT
NOT NULL
CHECK(employeeId > 0),
firstname VARCHAR(20)
NOT NULL,
lastname VARCHAR(20)
NOT NULL,
sex VARCHAR(1)
NOT NULL,
birthdate DATE
NOT NULL,
addressId VARCHAR(30),
PRIMARY KEY(employeeId)
);
CREATE TABLE address(
addressId VARCHAR(30)
NOT NULL,
employeeId INT,
Address1 VARCHAR(120)
NOT NULL,
Address2 VARCHAR(120),
Address3 VARCHAR(120),
City VARCHAR(100)
NOT NULL,
State CHAR(2)
NOT NULL,
Country CHAR(2)
NOT NULL,
PostalCode VARCHAR(16)
NOT NULL,
PRIMARY KEY(addressId),
FOREIGN KEY(employeeId) REFERENCES employee(employeeId) ON DELETE SET NULL
);
ALTER TABLE employee
ADD FOREIGN KEY(addressId)
REFERENCES address(addressId)
ON DELETE SET NULL;
I would love to know if there are any other ways to create an appropriate relationship between employee and address without using GUID. Another way would be a specified (int) value, but in that case a disadvantage would be:
Introducing by mistake a FK != PK which will lead to a poor relationship between the tables.
EDIT:
Some of you suggested in the comments to change "UUID" indexing to AUTO_INCREMENT but the problem for me arises when I have to insert employees from my WPF-application.
The PK addressId from address will keep increasing on its own. What am I supposed to pass into the FK then to keep the relationship tight and correct then?
Should I create a variable of type int, let's say var i = 0 and every time I insert one employee -> increase that variable by one -> assign it to the FK or?
You'll want something like this in order to do a many-to-many association between employees and addresses (Address types will be like home, work, billing, travel, etc.). You can then create other entity tables to track associations between those entities and addresses as well. In the table employee_address, those columns will be foreign keys back to their relative tables.
As for using GUIDs vs INT for primary keys, numeric values read faster than string values on a JOIN. Depending on how large your data gets, you may need to switch from INT to BIGINT years down the road.
Also, give these people some space to enter their names. 20 characters is way too short, especially for last names.
employee
--------
employee_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(255) NOT NULL,
lastname VARCAHR(255) NOT NULL,
gender BIT NOT NULL,
birthdate DATE NOT NULL
address
---------
address_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
address1 VARCHAR(255),
address2 VARCHAR(255),
address3 VARCHAR(255),
city VARCHAR(255),
state CHAR(2),
country CHAR(2)
address_type
--------------
address_type_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
address_type VARCHAR(255)
employee_address
-----------------
employee_address_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
employee_id INT,
address_id INT,
address_type_id INT
I need to create a table called benificiaries where I have three columns
customerid
accountno
bank
The condition should be one customerid can have only one unique accountno. But another customerid can have the same accountno and same unique (only once). So I cant give primary key to accountno. Even for customerid I can't give primary key, since one customerid can have multiple records with unique accountno.
How can we create table in this case? Any ideas?
You can use multiple-column unique index.
CREATE TABLE YOUR_TABLE (
id INT NOT NULL AUTO_INCREMENT,
customerid INT NOT NULL,
accountno INT NOT NULL,
bank INT NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX name (customerid,accountno)
);
Documentation here.
https://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html
If one customerid can have only 1 unique account number then how can you expect duplicates in terms of customer id in that table?
You can simply set a primary key to another column and make the customerid unique. I think this is what you want to have. Now every customerid is unique, but many costomerids can have the same accountno.
CREATE TABLE benificiaries(
id INT PRIMARY KEY,
customerid INT NOT NULL UNIQUE,
accountno INT NOT NULL,
bank INT NOT NULL
);
database can't manage all the business constraints within the data model. For the case, you might address elementary constraints with indexes (multiple column index for customerid, accountno and simple column index for accountno to perform search on the other way), add an auto-increment id and deal the business constraints in your code.
Just set your customer_id as a primary key then regarding the concept that a only two customer_id can have same account number once, will depend on the process of your App or System.
CREATE TABLE `tmpr_map`.`tbl_example`
(`customer_id` INT(11) NOT NULL AUTO_INCREMENT,
`account_number` VARCHAR NOT NULL , `bank_amount` DECIMAL(11,2) NOT NULL ,
PRIMARY KEY (`customer_id`)) ENGINE = InnoDB;
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.