You are on page 1of 17

1

Project 2: Data Design - Report

Amy Gonzales, Christopher Bray, Jerome Ortega and Nathan Jobes

Department of Computer Science, California State University Monterey Bay

CST363: Intro to Database Systems

Dr. David Wisneski

May 25, 2021


2

Introduction

In our analysis of the assignment requirements, we discussed as a group what sort of

entity or business would utilize a database like the one we were creating. In our reasoning,

hospitals and medical groups would require databases that contained physician information,

patient information and other data such as prescriptions, procedures and insurance information.

A pharmaceutical company would utilize a database that contained supplies, drug formulas,

clinical trial information in their scientific development sectors, and databases of companies that

sell their products in their financial departments. Pharmacies, hospitals and medical groups who

sell or otherwise provide medications to patients would utilize databases that contain drug cost,

inventory levels, and patient health data including prescribing physician, dates of filled

prescriptions and potential allergies/contraindication. The database we are assigned to create

contains blended information that could be useful to companies that track medication use or

abuse in specific demographics or geographical regions. It could be utilized by a government

health initiative to monitor the opioid epidemic, potentially tracking physicians who are

prescribing large quantities of harmful or addictive medication, or patients who could be filling

prescriptions at multiple pharmacies.With this in mind, we analyzed the specific requirements.

The database must contain patient and doctor information, both with an identifying social

security number and a name and more specific information for each. Each patient is assigned to

at least one doctor, and every doctor must have at least one patient. These doctors prescribe

prescriptions for their patients, with one or more drugs, with a date and quantity associated with

it. There must be tables to contain data for pharmacies, their name and location, the drugs they
3

sell and their cost, and patients who fill a prescription. When a prescription is filled, the date

should be tracked, and the pharmacy who filled it. The data for the pharmaceutical company

must contain a name, address and phone number, as well as formulas and a trade name as a

unique identifier. A long term contract binds the pharmaceutical companies with the pharmacies,

and information such as contract start and expiration dates, and the text of the contract. Each

contract must have a supervisor assigned by the pharmacy, but the supervisor may change over

time.

Entity Relationship Diagram Discussion

The patients table contains fields for a primary key social security number, and fields for

name, age and address, and we decided the name should be non nullable. The doctors table has a

primary key social security number and a non nullable name field. We allowed the specialty to be

a nullable field, with the understanding that this field would be null if the physician was a

general doctor and did not have a specialty. The years of experience was made nullable also, in

case this information was unknown at the time the physician was entered into the database. The

patients and doctors table are connected by the patients_has_doctors table, containing the

identifying social security number from each side in a many to many relationship, since patients

can have more than one doctor and doctors see many patients.

The pharmacies table contains an auto generated id number and fields for name, address

and phone number, and is related to the prescriptions table by the foreign key

filling_pharmacy_id, in a one to many relationship since a pharmacy will interact with multiple

prescriptions and a prescription will be filled by only one pharmacy. We made the name field non

nullable, but left the address and phone number nullable. The pharmacy table also relates to the

drugs table in a many to many relationship since one company manufactures many drugs and a
4

generic formula could be used by many companies to produce a drug with a specific trade name.

The drugs table has a trade name field which also serves as the primary key, as well as a foreign

key formula_id from the formulas table. We gave formulas its own table since a generic drug

could be manufactured by different companies using the same formula which may have the same

active ingredient but different concentrations.The pharmacies table and drugs table are related by

a pharmacies_has_drugs table which contains foreign keys pharmacies_id and drugs_id as well

as a decimal data type field for the price.

The contracts table uses the id numbers from the pharma_companies and pharmacies

table as foreign keys, along with the auto generated primary key from the supervisors table,

supervisors_employee_id. The contracts table has a one to many relationship with the

pharma_companies since one company could have many contracts, but may have no current

contracts. The pharmacies table is related to the supervisors table by the

pharmacies_has_supervisors tables which contains the identifier id number from both tables in a

one to many relationship since a supervisor will work for one pharmacy but a pharmacy may

employ many supervisors.

Entity Relationship Diagram

The diagram on the following page is our Entity Relationship diagram.


5
6

Schema

Below is our SQL script for building the full schema, with constraints, keys and other

requirements. Sample data is not presented.

CREATE SCHEMA CREATE TABLE drugs (


drug_store_chain_open_sorcerers; trade_name VARCHAR(45) NOT NULL,
USE drug_store_chain_open_sorcerers; formula_id INT NOT NULL,
PRIMARY KEY (trade_name),
-- Create table doctors CONSTRAINT
CREATE TABLE doctors ( fk_drugs_formulas1a
ssn INT NOT NULL, FOREIGN KEY (formula_id)
name VARCHAR(45) NOT NULL, REFERENCES formulas (id)
specialty VARCHAR(45) NULL, ON DELETE NO ACTION
years_experience INT NULL, ON UPDATE NO ACTION
PRIMARY KEY (ssn) );
);
-- Create table pharmacies
-- Create table patients CREATE TABLE pharmacies (
CREATE TABLE patients ( id INT NOT NULL AUTO_INCREMENT,
ssn INT NOT NULL, name VARCHAR(45) NOT NULL,
name VARCHAR(45) NOT NULL, address VARCHAR(45) NULL,
age INT NULL, phone VARCHAR(45) NULL,
address VARCHAR(100) NULL, PRIMARY KEY (id)
PRIMARY KEY (ssn) );
);
-- Create many to many with doctors and
-- Create table pharma_companies patients
CREATE TABLE pharma_companies ( CREATE TABLE patients_has_doctors (
id INT NOT NULL AUTO_INCREMENT, patients_ssn INT NOT NULL,
name VARCHAR(45) NOT NULL, doctors_ssn INT NOT NULL,
phone VARCHAR(45) NOT NULL, CONSTRAINT
PRIMARY KEY (id) fk_patients_has_doctors_patients
); FOREIGN KEY (patients_ssn)
REFERENCES patients (ssn)
-- Create table formulas ON DELETE NO ACTION
CREATE TABLE formulas ( ON UPDATE NO ACTION,
id INT NOT NULL AUTO_INCREMENT, CONSTRAINT
active_ingredient VARCHAR(45) NOT fk_patients_has_doctors_doctors1
NULL, FOREIGN KEY (doctors_ssn)
concentration DECIMAL(2) NOT NULL, REFERENCES doctors (ssn)
PRIMARY KEY (`id`) ON DELETE NO ACTION
); ON UPDATE NO ACTION
);
-- Create table drugs
7

-- Create many to many relationship for rxid int NOT NULL


pharmacies and drugs. AUTO_INCREMENT,
CREATE TABLE pharmacies_has_drugs ( patients_ssn INT NOT NULL,
pharmacies_id INT NOT NULL, doctors_ssn INT NOT NULL,
drug_trade_name VARCHAR(45) NOT drug_trade_name VARCHAR(45) NOT
NULL, NULL,
price DECIMAL(18, 2) NOT NULL, filling_pharmacy_id INT NULL,
CONSTRAINT filled_on DATE,
fk_pharmacies_has_drugs_pharmacies1 quantity INT NOT NULL,
FOREIGN KEY (pharmacies_id) PRIMARY KEY (rxid),
REFERENCES pharmacies (id) CONSTRAINT
ON DELETE NO ACTION fk_prescriptions_patients_has_doctors1
ON UPDATE NO ACTION, FOREIGN KEY (patients_ssn)
CONSTRAINT REFERENCES patients_has_doctors
fk_pharmacies_has_drugs_drugs1 (patients_ssn)
FOREIGN KEY (drug_trade_name) ON DELETE NO ACTION
REFERENCES drugs (trade_name) ON UPDATE NO ACTION,
ON DELETE NO ACTION CONSTRAINT
ON UPDATE NO ACTION fk_prescriptions_patient_has_doctors2
); FOREIGN KEY (doctors_ssn)
REFERENCES patients_has_doctors
-- Create many to many relationship (doctors_ssn)
between drugs and pharma companies. ON DELETE NO ACTION
CREATE TABLE ON UPDATE NO ACTION,
drugs_has_pharma_companies ( CONSTRAINT fk_prescriptions_drugs1
drugs_id VARCHAR(45) NOT NULL, FOREIGN KEY (drug_trade_name)
pharma_companies_id INT NOT NULL, REFERENCES drugs (trade_name)
CONSTRAINT ON DELETE NO ACTION
fk_drugs_has_pharma_companies_drugs1 ON UPDATE NO ACTION,
FOREIGN KEY (drugs_id) CONSTRAINT
REFERENCES drugs (trade_name) fk_prescriptions_pharmacies1
ON DELETE NO ACTION FOREIGN KEY
ON UPDATE NO ACTION, (filling_pharmacy_id)
CONSTRAINT REFERENCES pharmacies (id)
fk_drugs_has_pharma_companies_pharma_ ON DELETE NO ACTION
companies1 ON UPDATE NO ACTION
FOREIGN KEY );
(pharma_companies_id)
REFERENCES pharma_companies -- Create table supervisors
(id) CREATE TABLE supervisors (
ON DELETE NO ACTION employee_id INT NOT NULL,
ON UPDATE NO ACTION name VARCHAR(45) NOT NULL,
); phone VARCHAR(45) NOT NULL,
PRIMARY KEY (employee_id)
-- Create table prescriptions );
CREATE TABLE prescriptions (
8

-- Create table contracts


CREATE TABLE contracts ( -- Create many to many relationship
pharmacy_id INT NOT NULL, between pharmacies and supervisors.
pharma_company_id INT NOT NULL, CREATE TABLE
contract_copy LONGTEXT NOT NULL, pharmacies_has_supervisors (
start_date DATE NOT NULL, pharmacies_id INT NOT NULL,
end_date DATE NOT NULL, supervisors_id INT NOT NULL,
supervisors_employee_id INT NOT CONSTRAINT
NULL, fk_pharmacies_has_supervisors_pharmacies
CONSTRAINT 1
fk_pharmacies_has_pharma_companies_pha FOREIGN KEY (pharmacies_id)
rmacies1 REFERENCES pharmacies (id)
FOREIGN KEY (pharmacy_id) ON DELETE NO ACTION
REFERENCES pharmacies (id) ON UPDATE NO ACTION,
ON DELETE NO ACTION CONSTRAINT
ON UPDATE NO ACTION, fk_pharmacies_has_supervisors_supervisors
CONSTRAINT 1
fk_pharmacies_has_pharma_companies_pha FOREIGN KEY (supervisors_id)
rma_companies1 REFERENCES supervisors
FOREIGN KEY (employee_id)
(pharma_company_id) ON DELETE NO ACTION
REFERENCES pharma_companies ON UPDATE NO ACTION
(id) );
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_contracts_supervisors1
FOREIGN KEY
(supervisors_employee_id)
REFERENCES supervisors
(employee_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);

There was only one significant code constraint (outside of validation) to be implemented

in the front end application. As the database uses the RXID for the primary key for all

prescriptions, the application must check the database for existing prescriptions with the same

doctor, patient and drug combination. This is to enforce only one allowed prescription for each

drug per doctor/patient relation. If an existing relation is found, the application replaces the new

prescription with the old one.


9

Normalization

There were a few steps to normalize our model, clearly all of our tables were in first

normalized form by default as we used the ER tool to design them. As it is possible for some of

our entities to share information and have partial dependencies, some steps were taken to

mitigate these issues. For example, different companies can produce the same drug formulas

under different trade names, so we seperated formulas from the drugs entity. This removes that

partial dependency and increases the normalization of the database. Although our tables are all in

second normal form, some are not in third normal form. This however is acceptable as there is

little to be gained from this additional normalization. Some transitive dependencies that exist for

example are the supervisor id and the supervisor name. Creating an additional relation would

increase normalization, however the benefit is negligible.

Queries

1. Can I find the start date, end date, pharmacy name, drug name, and the pharma company of a

contract for the drug called Motrin?

SELECT

contracts.start_date AS contract_start_date,

contracts.end_date AS contract_end_date,

pharmacies.name AS pharmacy_name,

drugs.trade_name AS drug_trade_name,

pharma_companies.name AS pharma_company_name

FROM contracts

JOIN pharmacies ON contracts.pharmacy_id = pharmacies.id


10

JOIN pharmacies_has_drugs ON pharmacies.id = pharmacies_has_drugs.pharmacies_id

JOIN drugs ON pharmacies_has_drugs.drug_trade_name = drugs.trade_name

JOIN pharma_companies ON contracts.pharma_company_id = pharma_companies.id

WHERE drugs.trade_name = 'Motrin';

2. Can I find the lowest price that Motrin is sold for across all of our pharmacy locations?

-- Minimum price of a given drug across all pharmacies.

SELECT pharmacy_name, drug_trade_name, price FROM (

SELECT

pharmacies.name AS pharmacy_name,

drugs.trade_name AS drug_trade_name,

price

FROM pharmacies_has_drugs

JOIN pharmacies ON pharmacies_has_drugs.pharmacies_id = pharmacies.id

JOIN drugs ON pharmacies_has_drugs.drug_trade_name = drugs.trade_name

WHERE drugs.trade_name = 'Motrin'

) AS Motrins

WHERE price = (

SELECT min(price) AS minPrice FROM (

SELECT

pharmacies.name AS pharmacy_name,

drugs.trade_name AS drug_trade_name,

price
11

FROM pharmacies_has_drugs

JOIN pharmacies ON pharmacies_has_drugs.pharmacies_id = pharmacies.id

JOIN drugs ON pharmacies_has_drugs.drug_trade_name = drugs.trade_name

WHERE drugs.trade_name = 'Motrin'

) AS Motrins

);

3. Which patients are currently seeing Dr. Amy Gonzales?

SELECT patients.name, doctors.name FROM patients, patients_has_doctors, doctors

WHERE doctors.ssn = patients_has_doctors.doctors_ssn

AND patients.ssn = patients_has_doctors.patients_ssn

AND doctors.name = 'Amy Gonzales';

4. How many contracts are being supervised by our supervisor Jimmy Johns?

SELECT count(*) as number_of_contracts FROM (

SELECT * FROM contracts, supervisors

WHERE contracts.supervisors_employee_id = supervisors.employee_id

AND supervisors.name = "Jimmy Johns"

) AS new_table;

5. How many are using each active ingredient?

SELECT formulas.active_ingredient, COUNT(formulas.id) AS productCount FROM drugs

JOIN formulas ON formulas.id = drugs.formula_id


12

GROUP BY formulas.active_ingredient;

Screenshots

Below are examples of the front end application at work.

Valid Data Entry Successful Prescription

Prescription Error Page

Invalid Data Entry


13

Overwrite Prescription Entry Successful Prescription Overwrite

Valid Data Fill Request Successful Prescription Fill


14

Invalid Data Fill Request Fill Request Error Page

Valid Data for Drug Report Successful Drug Report

Invalid Data Entry Drug Report Error Page


15

Valid Data FDA Report Successful FDA Report Page

Invalid Data Entry for FDA Report FDA Report Error Page
16

Valid Partial Data for FDA Report

Valid Partial Results for FDA Report

Conclusion

We have learned how an ER diagram works and have executed creating our own ER

diagram. We logically made accurate the cardinality for relationships in our diagram and have

identified primary keys for all entities. We then mapped the ER diagram to relational database

schema. We wrote down the database schema as SQL create table statements. We then checked

our relational schema for normal form. After that, we documented any functional dependencies
17

that would indicate the need for normalization. We also thought of at least 5 questions about the

data that would be interesting to management of the drug store chain. We then wrote each of

them in SQL. We also created test data in our tables that demonstrated our SQL query was

working correctly.

After designing the database, our team wrote a relational schema derived from the ER

model. In the report we presented the schema in SQL as CREATE TABLE statements. We

included foreign key constraints and updated and deleted rules, “not null” or “null” column

properties, SQL check constraints, and any other constraints that cannot be implemented in SQL

and must be done by application code. We normalized the relational schema. We included our

SQL queries and included particular ones that express the queries in the report.

Our team learned a lot through the process of performing the work entailed in this

project. For example we were unaware how much more intuitive it would be to be able to

visually see the relationships created using the ER diagram. Having the boxes with the types of

relationships to look at made hammering it out, to make sense in the real world, a lot simpler. We

found that having the ER diagram to consult made it possible to scan over the entire database

easily and quickly find errors in logic and design.

You might also like