Good and Bad Database Design
by K. Yue
1. Introduction
Example:
Consider the relation
EMPLOYEE(EMP_NO, NAME, DEPT_NO, MANAGER_NO).
Assumptions made:
Thus, EMP_NO is a candidate key.
EMP_NO | NAME | DEPT_NO | MANAGER_NO |
10000 | Lady Gaga | D123 | 54321 |
12000 | Brad Pitts | D123 | 54321 |
13000 | Lebron James | D123 | 54321 |
21000 | Narendra Modi | D225 | 42315 |
22000 | Jennifer Lopez | D225 | 42315 |
31000 | John Smiths | D337 | 33323 |
Problem:
Update Anomaly:
(a) 44444 is the new manager of department D123
EMP_NO | NAME | DEPT_NO | MANAGER_NO |
10000 | Lady Gaga | D123 | 44444 |
12000 | Brad Pitts | D123 | 44444 |
13000 | Lebron James | D123 | 54321 ?? |
21000 | Narendra Modi | D225 | 42315 |
22000 | Jennifer Lopez | D225 | 42315 |
31000 | John Smiths | D337 | 33323 |
(b) Jennifer Lopez changes to working for department D337:
EMP_NO | NAME | DEPT_NO | MANAGER_NO |
10000 | Lady Gaga | D123 | 54321 |
12000 | Brad Pitts | D123 | 54321 |
13000 | Lebron James | D123 | 54321 |
21000 | Narendra Modi | D225 | 42315 |
22000 | Jennifer Lopez | D337 | 42315 ?? |
31000 | John Smiths | D337 | 33323 |
The command:
UPDATE Employee
SET DEPT_NO = 'D337'
WHERE NAME = 'Jennifer Lopez';
will produces inconsistent result.
Insertion Anomaly:
Creating a new department D777, with manager 77111, currently with no employee is not possible.
EMP_NO | NAME | DEPT_NO | MANAGER_NO |
10000 | Lady Gaga | D123 | 54321 |
12000 | Brad Pitts | D123 | 54321 |
13000 | Lebron James | D123 | 54321 |
21000 | Narendra Modi | D225 | 42315 |
22000 | Jennifer Lopez | D225 | 42315 |
31000 | John Smiths | D337 | 33323 |
???? | ???? | D777 | 77111 |
Deletion Anomaly:
John Smiths no longer works here. Result: the information that 33323 is the manager of department D337 is lost.
EMP_NO | NAME | DEPT_NO | MANAGER_NO |
10000 | Lady Gaga | D123 | 54321 |
12000 | Brad Pitts | D123 | 54321 |
13000 | Lebron James | D123 | 54321 |
21000 | Narendra Modi | D225 | 42315 |
22000 | Jennifer Lopez | D225 | 42315 |
A standard way of resolving these issues are by proper decomposition: breaking down a relation into two or more relations.
Example: decomposition into two relations:
EMP(EMP_NO, NAME, DEPT_NO)
EMP_NO | NAME | DEPT_NO |
10000 | Lady Gaga | D123 |
12000 | Brad Pitts | D123 |
13000 | Lebron James | D123 |
21000 | Narendra Modi | D225 |
22000 | Jennifer Lopez | D225 |
31000 | John Smiths | D337 |
DEPARTMENT(DEPT_NO, MANAGER_NO)
DEPT_NO | MANAGER_NO |
D123 | 54321 |
D225 | 42315 |
D337 | 33323 |
To obtain the original relation EMPLOYEE(EMP_NO, NAME, DEPT_NO, MANAGER_NO) from
EMP(EMP_NO, NAME, DEPT_NO)
DEPARTMENT(DEPT_NO, MANAGER_NO)
SQL:
SELECT EMP.*, DEPARTMENT.MANAGER_NO INTO EMPLOYEE
FROM EMP, DEPARTMENT
WHERE EMP.DEPT_NO = DEPARTMENT.DEPT_NO
Methods for good designs
Integrity Rules:
Examples:
General Integrity Rules:
Entity Integrity Rule
Example:
EMPLOYEE(EMP_NO, NAME, DEPT_NO, SALARY)
EMP_NO | NAME | DEPT_NO | SALARY |
10000 | Lady Gaga | D123 | 550000000 |
12000 | Brad Pitts | D123 | 10000000 |
13000 | Lebron James | D123 | 50000000 |
21000 | Narendra Modi | @ | @ |
@ | Jennifer Lopez | D225 | 2000000 |
@ | John Smiths | D337 | 70000 |
Referential Integrity Rule
Example:
EMP(EMP_NO, NAME, DEPT_NO)
EMP_NO | NAME | DEPT_NO |
10000 | Lady Gaga | D123 |
12000 | Brad Pitts | D123 |
13000 | Lebron James | @ |
21000 | Narendra Modi | D225 |
22000 | Jennifer Lopez | D225 |
31000 | John Smiths | D337 |
DEPARTMENT(DEPT_NO, MANAGER_NO)
DEPT_NO | MANAGER_NO |
D123 | 54321 |
D225 | 42315 |
D337 | 33323 |
Example:
EMP(EMP_NO, NAME, DEPT_NO)
EMP_NO | NAME | DEPT_NO |
10000 | Lady Gaga | D123 |
12000 | Brad Pitts | D123 |
13000 | Lebron James | D123 |
21000 | Narendra Modi | D225 |
22000 | Jennifer Lopez | D225 |
31000 | John Smiths | D337 |
32000 | Bun Yue | D119 |
DEPARTMENT(DEPT_NO, MANAGER_NO)
DEPT_NO | MANAGER_NO |
D123 | 54321 |
D225 | 42315 |
D337 | 33323 |
Note: