Mysql: enum confusion - sql

I have an employee table, employee has interests, so the table can be designed like this:
create table emp(
id int(10) not null auto_increment,
name varchar(30),
interest varchar(50),
primary key(id)
);
or this:
create table emp(
id int(10) not null auto_increment,
name varchar(30),
interest enum('football','basketball','music','table tennis','volleyball'),
primary key(id)
);
The number of interests can be about 50.
How should i design the table? Should i use enum or others ?
Edit:
Thanks for your reponse.
Assume that a person can be a Mr. or Madame or Ms.
I make a drop down list in PHP.
<select name="role">
<option value="Mr.">Mr.</option>
<option value="Ms">Ms</option>
<option value="Madame">Madame</option>
</select>
And for the DB part, I can do this:
create table emp(
id int(10) not null auto_increment,
name varchar(30),
role varchar(50),
primary key(id)
);
or this:
create table emp(
id int(10) not null auto_increment,
name varchar(30),
role enum('Mr.','Ms.','Madame'),
primary key(id)
);
In this context, which is better?

There's a third option, creating an additional table for holding the interest values.
INTERESTS
interest_id, int, primary key
interest_value, string/varchar, unique constraint (to stop duplicates)
Many-to-Many Relationship?
However, if you want to support an employee having multiple interests you'll need a third table. This is a many-to-many relationship - the third table would sit between the EMPLOYEES and INTERESTS tables, and have foreign key relationships with both.
EMPLOYEE_INTERESTS
employee_id, primary key, foreign key to EMPLOYEES.id
interest_id, primary key, foreign key to INTERESTS.interest_id
One-to-Many Relationship?
If an EMPLOYEES record can only ever have one INTEREST, then you only need to update the EMPLOYEES.interest column to have a foreign key relationship with the INTERESTS table.
EMPLOYEES
interest_id, primary key, foreign key to INTERESTS.interest_id

You should really make 3 tables, assuming that an employee can have multiple interests. (Your current design limits each employee to 1 interest.) Something like this:
Employee (emp)
-------
id
name
Interest
-------
id
description
Employee_Interest
--------
employeeID
interestID
Regarding the edit, I'd say the enum is the better of your 2 examples as it limits you to predetermined allowable values. But many would argue that you should make a lookup table (Role with id and description) even for that

Related

How to check for not null value in relationship table in PostgreSQL?

I have these three tables in a PostgreSQL db and as you can see books has an author field (referencing users) and users has a company_id field referencing companies.
create table companies (
id serial primary key,
name varchar not null
);
create table users (
id serial primary key,
email varchar not null,
company_id int,
constraint fk_company
foreign key(company_id)
references companies(id)
);
create table books (
id serial primary key,
title varchar not null,
author_id integer not null,
constraint fk_author
foreign key(author_id)
references users(id)
);
A user may or may not belong to a company, but to create a book the user must have a company reference.
I am wondering if there is a way to implement a CHECK constraint on the author_id column which would ensure that the author has a company reference.
Maybe something like: author_id integer not null CHECK(users.company_id is not null), but of course this doesn't work.
Is there some sort of constraint I can use to check columns in relations?
Also am I even approaching this problem in the right way?
Thanks in advance. :)
Looking at constraints:
A Publisher can have zero or more publications.
An Author/User can have zero or more books Authored.
A Book will have one Publisher & one or more Authors.
Move the company_id constraint to books table. If & when an User/Author[s] publishes a book; They become a new Publishing Company and an entry to Publishing Company.

Create 2 tables having same column but not a primary key

( Question is only for a college project as I'm stuck with the requirement)
I want to create 2 tables in SQL Server, say 'table1' and 'table2' in the same database. Both should have a column say 'col1' which is not a primary key.
So how should I create it so that when I insert data into one table, the other gets updated automatically?
NOTE: So this is for a college project, we are asked to make a specific type of primary keys so referencing that is not an option, now I have to have same entity in 2 different tables, so is a good idea to somehow reference them, any ideas?
For eg, en employee's project details will have his/her empID and the dependants' table will have empID as well. But I cannot make it primary key since that is already defined by the Professor. But updating one should update another as well, does that make sense?
You can have two types of parent-child relationship.
Identifying relationship : Here, child depends on the parent to identify itself. E.g. Project requires Employee to exist. Here, Project should have EmployeeId part of its primary key or EmployeeId as its primary key. If EmployeeId is primary key of project then, an employee can have only one project.
CREATE TABLE Employee
(
EmployeeId INT,
EmployeeName VARCHAR(255) NOT NULL,
PRIMARY KEY(EmployeeId)
)
GO
CREATE TABLE EmployeeProject
(
EmployeeId INT,
EmployeeName VARCHAR(255) NOT NULL,
PRIMARY KEY(EmployeeId),
FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId),
)
GO
Non-identifying relationship: Here, child does not depend on the parent to identify itself. E.g. Project can be defined without Employee. Here, Project can have EmployeeId as foreign key. If EmployeeId is NOT NULL column, then it is mandatory to have an employee. If EmployeeId is NULL column, then it is not mandatory to have an employee.
CREATE TABLE Employee
(
EmployeeId INT,
EmployeeName VARCHAR(255) NOT NULL,
PRIMARY KEY(EmployeeId)
)
GO
CREATE TABLE EmployeeProject
(
EmployeeProjectId INT,
EmployeeName VARCHAR(255) NOT NULL,
EmployeeId INT NOT NULL, -- Can be NULL, if it is not mandatory
PRIMARY KEY(EmployeeProjectId),
FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId),
)
GO
First while creating tables, the entity which is to be refereced as foreign key, make it unique:
Table1:
[SIN] int NOT NULL UNIQUE,
Second, in another table where calling [SIN] as FK, put conditions for update and delete:
Table2:
[SIN] INT CONSTRAINT [SIN_FK1] FOREIGN KEY REFERENCES Employee([SIN]) ON DELETE SET NULL ON UPDATE CASCADE
By doing this, whenever you update or delete records in Table1, the corresponding record in Table2 will be updated.

How to create zero or one to many relationship using sql

I have this data model generated by EntityFramework in an existing application but i want to create the same tables with the same relationships in my database.
I succeeded creating the relationship (one to zero or one) between Student and StudentAddress with the following query which is correct:
CREATE TABLE Student(
StudentId INT NOT NULL PRIMARY KEY,
FirstName VARCHAR(30),
LastName VARCHAR(30),
City VARCHAR(30),
State1 VARCHAR(30),
StandardId INT NOT NULL FOREIGN KEY REFERENCES Standard(StandardId));
CREATE TABLE StudentAddress(
StudentId INT,
Adress1 VARCHAR(30),
Adress2 VARCHAR(30),
City VARCHAR(30),
State VARCHAR(30),
CONSTRAINT StudentAdress_PK PRIMARY KEY(StudentId),
CONSTRAINT StudentAdress_Student_FK FOREIGN KEY(StudentId)
REFERENCES Student(StudentId));
My question is considering this data model how to create the relationship (zero or one to many) between Standard and Student tables.
Thank you for your help
You do this the same way that you implemented the one to zero or one relationship.
So far you have a foreign key in StudentAddress to Student. There is nothing enforcing one address per student. (You could do so with a unique index on `StudentAddress.StudentId'.)
So do the same thing. Have a StandardId field in the Student table, and you will have a many Student to zero or one Standard relationship.
You need a third table that stores the relationships:
CREATE TABLE StandardStudenRelation (
ID INT IDENTITY(1,1) PRIMARY KEY
, StandardID INT NOT NULL
, StudentID INT NOT NULL
, CONSTRAINT Student_ID_FK FOREIGN KEY(StudentId)
REFERENCES Standard(StudentId)
, CONSTRAINT Standard_ID_FK FOREIGN KEY(StandardID)
REFERENCES Standard(StandardId)
);

Foreign key referring to more than one primary key values(from one table) - Oracle SQL PLUS

I am still a beginner in SQL and i'm facing an issue. hope you can help me.
I have a table called Department where it has an attribute DEPARTMENT_NO as its primary key.
CREATE TABLE DEPARTMENT(
DEPARTMENT_NO INT NOT NULL,
NAME VARCHAR(25) NOT NULL,
LOCATION CHAR(15),
PRIMARY KEY(DEPARTMENT_NO));
I have another table called Doctor where it has an attribute DNUM as a foreign key referring to DEPARTMENT_NO :
CREATE TABLE DOCTOR(
DOCTOR_ID CHAR(9) NOT NULL,
DNUM INT NOT NULL,
NAME VARCHAR(20) NOT NULL,
DOB DATE,
SPECIALTY VARCHAR(20) NOT NULL,
SALARY INT,
CITY VARCHAR(15),
STREET VARCHAR(15),
START_DATE DATE,
PRIMARY KEY(DOCTOR_ID))
FOREIGN KEY(DNUM) REFERENCES DEPARTMENT(DEPARTMENT_NO));
A doctor can be working in one or two departments. So, if I have a doctor working in department 1 and 4 (the values for DNUM will include 1 and 4).
I initially chose the data type of DNUM to be INT(same as DEPARTMENT_NO data type). But INT is not ideal for multiple values.
What should the data type be? or what other solution i have if,for example, I run a query for returning the name of the doctors working in department 4.
The query should return all the names of doctors working in department 4(only) and the ones who work in multiple departments(including 4).
Thanks very much in advance and sorry for the long message.
The standard way to represent a "many to many" relationship is via a "junction" (aka "link") table:
CREATE TABLE DOCTOR_DEPARTMENT (
DOCTOR_ID INT REFERENCES DOCTOR(DOCTOR_ID),
DEPARTMENT_NO INT REFERENCES DEPARTMENT (DEPARTMENT_NO),
PRIMARY KEY (DOCTOR_ID, DEPARTMENT_NO)
);
Note the key on {DOCTOR_ID, DEPARTMENT_NO}, which ensures the same doctor cannot be connected to the same department twice.
It also implicitly creates a composite (aka. "concatenated") index on these fields in that order, which makes it very quick to find departments of a given doctor (via an index range scan). If you need to query in the opposite "direction" (for doctors of the given department), flip the order of fields. If you need both queries, then you'll need both indexes (i.e. you'll need to create one index explicitly).
Consider adding ORGANIZATION INDEX clause, if you need just one of these indexes.
You need an additional table called doctor_department
create table doctor_department
(doctor_id integer references doctor(doctor_id) not null,
dnum integer references department(dnum) not null
)
You can create another table with relation to these 2 tables
Say,
Create table Dept_Doctors(
ID int not null,
DOCTOR_ID char(9) not null,
DEPARTMENT_NO INT NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY(DEPARTMENT_NO) REFERENCES DEPARTMENT(DEPARTMENT_NO),
FOREIGN KEY(DOCTOR_ID) REFERENCES DOCTOR(DOCTOR_ID));
You can join the 3 tables and get the desired result.

Enforce constraints between tables

How do you establish a constraint where, one column (not the primary key) has to have the same value as another table's column. I'm not quite sure how to phrase it so here's an example:
Ex:
I have three tables, Employee, Director, Division and Department
The structure for the tables are as follows:
Employee
Id
Name
DirectorId (FK)
DepartmentID (FK)
Director
Id
Name
DepartmentID (FK)
Department
Id
Name
DivisionId (FK)
Division
Id
Name
Employees and directors both have departments, each department has a division but their divisions have to be the same. Is there a way to enforce this? (Hopefully without having to resort to triggers)
Create stored procedures that will have proper GRANTS and don't allow user to INSERT into table directly. Use stored procedures as interface to the database, and check required conditions in them before insertion.
First, your example tables are doing too much. There is a design principle that states that a single table should model an entity or a relationship between entities but not both. The relationships between departments, directors and employees (I'm assuming that directors are not employees; I'm also omitting divisions for the moment).
Second, a table can have more than one key, known as candidate keys. Further, you can create a UNIQUE constraint by 'appending' a non-unique column to a key. For example, employees' names do not make for a good key, hence the reason for having an employee ID (I don't think the same can be said for departments i.e. department name in itself is a good enough key). If employee_ID is unique then it follows that (employee_name, employee_ID) will also be unique.
Third, a table can be referenced by any UNIQUE constraint, it doesn't have to be the table's 'primary' key (which partly explains why 'primary key' is a bit of a nonsense).
The great thing about the above is that one can model the required constraints using FOREIGN KEY and row-level CHECK constraints. SQL optimizers and programmers prefer declarative solutions to procedural code (triggers, stored procs, etc). This vanilla SQL DDL will port to most SQL products.
So, the department name can be combined with both the director key and the employee key respectively and these compound keys can be referencesd in a simple two-tier org chart table: because both the employee's department and their director's department will appear in the same table, a simple row-level CHECK constraint can be used to test that they are the same e.g.
Entity tables:
CREATE TABLE Departments
(
department_name VARCHAR(30) NOT NULL UNIQUE
);
CREATE TABLE Employees
(
employee_ID INTEGER NOT NULL UNIQUE,
employee_name VARCHAR(100) NOT NULL
);
CREATE TABLE Directors
(
director_ID INTEGER NOT NULL UNIQUE,
director_name VARCHAR(100) NOT NULL
);
Relationship tables:
CREATE TABLE EmployeeDepartments
(
employee_ID INTEGER NOT NULL UNIQUE
REFERENCES Employees (employee_ID),
employee_department_name VARCHAR(30) NOT NULL
REFERENCES Departments (department_name),
UNIQUE (employee_department_name, employee_ID)
);
CREATE TABLE DirectorDepartments
(
director_ID INTEGER NOT NULL UNIQUE
REFERENCES Directors (director_ID),
director_department_name VARCHAR(30) NOT NULL
REFERENCES Departments (department_name),
UNIQUE (director_department_name, director_ID)
);
CREATE TABLE OrgChart
(
employee_ID INTEGER NOT NULL UNIQUE,
employee_department_name VARCHAR(30) NOT NULL,
FOREIGN KEY (employee_department_name, employee_ID)
REFERENCES EmployeeDepartments
(employee_department_name, employee_ID),
director_ID INTEGER NOT NULL,
director_department_name VARCHAR(30) NOT NULL,
FOREIGN KEY (director_department_name, director_ID)
REFERENCES DirectorDepartments
(director_department_name, director_ID),
CHECK (employee_department_name = director_department_name)
);
Now a slightly more interesting scenario would be when a director is assigned a division, rather than a specific department, and you had to test that the employee's department was in the same division as her director:
Entity tables:
CREATE TABLE Divisions
(
division_name VARCHAR(20) NOT NULL UNIQUE
);
CREATE TABLE Departments
(
department_name VARCHAR(30) NOT NULL UNIQUE,
division_name VARCHAR(20) NOT NULL
REFERENCES Divisions (division_name),
UNIQUE (division_name, department_name)
);
CREATE TABLE Employees
(
employee_ID INTEGER NOT NULL UNIQUE,
employee_name VARCHAR(100) NOT NULL
);
CREATE TABLE Directors
(
director_ID INTEGER NOT NULL UNIQUE,
director_name VARCHAR(100) NOT NULL
);
Relationship tables:
CREATE TABLE EmployeeDepartments
(
employee_ID INTEGER NOT NULL UNIQUE
REFERENCES Employees (employee_ID),
employee_department_name VARCHAR(30) NOT NULL
REFERENCES Departments (department_name),
UNIQUE (employee_department_name, employee_ID)
);
CREATE TABLE DirectorDivisions
(
director_ID INTEGER NOT NULL UNIQUE
REFERENCES directors (director_ID),
director_division_name VARCHAR(20) NOT NULL
REFERENCES divisions (division_name),
UNIQUE (director_division_name, director_ID)
);
CREATE TABLE OrgChart
(
employee_ID INTEGER NOT NULL UNIQUE,
employee_department_name VARCHAR(30) NOT NULL,
FOREIGN KEY (employee_department_name, employee_ID)
REFERENCES EmployeeDepartments
(employee_department_name, employee_ID),
employee_division_name VARCHAR(20) NOT NULL
REFERENCES divisions (division_name),
FOREIGN KEY (employee_division_name, employee_department_name)
REFERENCES Departments (division_name, department_name),
director_ID INTEGER NOT NULL,
director_division_name VARCHAR(20) NOT NULL,
FOREIGN KEY (director_division_name, director_ID)
REFERENCES DirectorDivisions
(director_division_name, director_ID),
CHECK (employee_division_name = director_division_name)
);
There is no limitation on creating foreign keys--there's nothing to stop you from defining a foreign key constraint on these tables:
EMPLOYEE
DIRECTOR
...associating them to the DEPARTMENT table. Though frankly, I don't see the need for a DIRECTOR table--that should be either a boolean indicator in the EMPLOYEE table, or possibly an EMPLOYEE_TYPE_CODE with it's own foreign key constraint to distinguish between employees and directors.
Multiple Foreign Keys
The presence of a foreign key also doesn't stop you from putting a second (or third, etc) constraint on the same column. Consider the scenario of TABLE_C.column having foreign key constraints to both TABLE_A.col and TABLE_B.col -- this is perfectly acceptable in the database, but it means that only values that exist in both TABLE_A.col and TABLE_B.col can exist in the TABLE_C.column. IE:
TABLE_A
col
----
a
b
c
TABLE_B
col
----
c
Based on this example data, TABLE_C.column could only ever allow "c" as value to exist in the column if someone added two foreign key constraints to the TABLE_C.column, referencing TABLE_A.col and TABLE_B.col.