You are on page 1of 24

Walgreens Company Database

Team 18 Project Report

CST 363: Intro to Database Systems

Aimen Altaiyeb, Jose Alvarado, Joshua Hansen

MagnifiCorp, Inc.
Team 18 Project Report - CST363
2
Project Overview

Magnificorp Incorporated has been given the task of creating an operational database for the
Walgreens drug store chain. Said database will keep record of patients, doctors, patient prescriptions,
pharmaceutical corporations and the drugs they manufacture, and pharmacy information. The
database will store the name of each pharmacy along with its address and phone number.

A patient will be required to have a unique social security number and must provide their legal name,
age, and address. The patient will need to fill a prescription at a pharmacy which will need to keep
record of the drug listed on each prescription as well as the date and location of the pharmacy at
which it was filled. The prescription will have a date given by the physician as well as a specific
quantity of which it is valid for. Any physician may write a single prescription(with a unique RX
number) for a single drug for any one patient. However, a single patient may have multiple
prescriptions from multiple doctors. Said doctors must also be documented in the database with a
unique social security number as well as their name, specialty, and years of experience in their
respective field. Every patient will have one of these doctors assigned as their primary care physician.

Drugs used in prescriptions will be manufactured and sold by a pharmaceutical company, whose
name and phone number will be stored in the database. The pharmaceutical company will give each
drug a unique trade name as well as list its genetic formula. Pharmacies will sell a variety of drugs,
each with its own price point. However, a single drug may be sold at different pharmacies with
different price points.

Lastly, in order for pharmaceutical companies to sell their drugs they must establish long term
contracts with a single or multiple pharmacies. Each contract is to be managed by a
pharmacy-appointed supervisor who may change during the duration of the contract. The database
will store the start date of each contract, the end date, and the text specifics of each contract.
Pharmacies may have multiple contracts with multiple pharmaceutical companies and a single
supervisor can oversee multiple contracts at once.
Team 18 Project Report - CST363
3
ER Model
Team 18 Project Report - CST363
4
Database Design Process

The strong entities in our above model include Doctor, Patient, Prescription, Drug, Pharmaceutical
Company, Pharmacy, and supervisor. Drug listing and Contract are weak entities as they are results
of relationships between the strong entities. The entities and relationships address the requirements
by keeping an accurate record of each instance of an entity without having to include unnecessary
information, i.e. a patient entity would have no need to store any information about a pharmacy
supervisor.

A recurring point of interest in our project design was selecting the keys for each of the entities used
in the database. Each entity had a unique identifier in it’s attributes, however a selection of those
entities had sensitive real word meaning in their key candidates, such as social security numbers for
patients and doctors. The names of the pharmacies and pharmaceutical companies also left room for
error as users would have to worry about spelling. We ultimately decided to use surrogate keys for all
entities as this would facilitate their organization.

We originally determined that the date of a prescription being filled should be functionally related to
specific drug listing, pharmacy, and other data local to that instance of the actual filling. Thus, we
intended a separate transaction table that would have a 1x1 relationship with prescription and have
its own surrogate key. This would have allowed the schema to be expandable for future use that
might involve relations between pharmacists and specific transactions. However, in order to keep the
prescription table design in accordance with the methodology set forth in the pre-existing end user
program design, fields that would have otherwise been separated out into a separate transaction
table have been included directly in the prescription table. This includes the date that the prescription
was filled as well as pharmacy details. These details are intended to be null when a prescription is
first added, then filled in at the time of the prescription being filled.

Normalization

Through our team meeting discussion and by the ER diagram tool we verified that we were using a
top-down design to lessen the need for normalization. However, we also manually checked over the
design for normalization. We first ensure that no field of a relation, or row, will contain multiple values
of that column. We have ensured that no partial functional dependencies are present. Thus, there are
no instances of a single value of a composite key determining the value of another column in a given
table. Finally, we’ve verified that there are no transitive dependencies, and so no non-key values
define another non-key column within the same table. Consequently there are no non-key defining
value duplicated within a record, and all records are as independent as possible. For example, we
ensured that pharmacy details were not included in the prescription table as these belonged in the
pharmacy table. We also had originally designed the prescription fill date to be included in a separate
transaction table that had a one-to-one relationship with the prescription table. However, due to end
user client code requirements, we needed to add the fill date and pharmacy id to the prescription
table. Thus, to keep the schema normalized, we removed the transaction table.
Team 18 Project Report - CST363
5
Relational Schema

-- MySQL Workbench Forward Engineering

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;


SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE,
SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_D
ATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

-- -----------------------------------------------------
-- Schema project1
-- -----------------------------------------------------
DROP SCHEMA IF EXISTS `project1` ;

-- -----------------------------------------------------
-- Schema project1
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `project1` DEFAULT CHARACTER SET utf8 ;
USE `project1` ;

-- -----------------------------------------------------
-- Table `project1`.`doctor`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`doctor` (
`doctor_id` INT NOT NULL AUTO_INCREMENT,
`ssn` VARCHAR(45) NOT NULL,
`name` VARCHAR(45) NOT NULL,
`specialty` VARCHAR(45) NOT NULL,
`practice_since_year` VARCHAR(45) NOT NULL,
PRIMARY KEY (`doctor_id`),
UNIQUE INDEX `doctor_id_UNIQUE` (`doctor_id` ASC) VISIBLE,
UNIQUE INDEX `doctor_ssn_UNIQUE` (`ssn` ASC) VISIBLE)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`patient`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`patient` (
`patient_id` INT NOT NULL AUTO_INCREMENT,
`ssn` VARCHAR(45) NOT NULL,
`name` VARCHAR(100) NOT NULL,
Team 18 Project Report - CST363
6
`birthdate` VARCHAR(45) NOT NULL,
`street` VARCHAR(100) NOT NULL,
`city` VARCHAR(100) NOT NULL,
`state` VARCHAR(45) NOT NULL,
`zipcode` VARCHAR(45) NOT NULL,
`primary_id` INT NOT NULL,
PRIMARY KEY (`patient_id`),
INDEX `fk_patient_doctor1_idx` (`primary_id` ASC) VISIBLE,
UNIQUE INDEX `patient_id_UNIQUE` (`patient_id` ASC) VISIBLE,
UNIQUE INDEX `patient_ssn_UNIQUE` (`ssn` ASC) VISIBLE,
CONSTRAINT `fk_patient_doctor1`
FOREIGN KEY (`primary_id`)
REFERENCES `project1`.`doctor` (`doctor_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`pharmacy`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`pharmacy` (
`pharmacy_id` INT NOT NULL AUTO_INCREMENT,
`pharmacy_name` VARCHAR(45) NOT NULL,
`street` VARCHAR(45) NULL DEFAULT NULL,
`city` VARCHAR(45) NULL DEFAULT NULL,
`state` VARCHAR(45) NULL DEFAULT NULL,
`zip` INT NULL DEFAULT NULL,
`phone_num` INT NULL DEFAULT NULL,
PRIMARY KEY (`pharmacy_id`),
UNIQUE INDEX `pharmacy_id_UNIQUE` (`pharmacy_id` ASC) VISIBLE)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`prescription`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`prescription` (
`rxid` INT NOT NULL AUTO_INCREMENT,
`quantity` VARCHAR(45) NOT NULL,
`patient_ssn` VARCHAR(45) NOT NULL,
`doctor_ssn` VARCHAR(45) NOT NULL,
`pharmacy_id` INT NULL DEFAULT NULL,
Team 18 Project Report - CST363
7
`drug_name` VARCHAR(100) NOT NULL,
`fill_date` DATE NULL DEFAULT NULL,
`request_date` DATE NOT NULL,
PRIMARY KEY (`rxid`),
INDEX `fk_prescription_doctor1_idx` (`doctor_ssn` ASC) VISIBLE,
UNIQUE INDEX `prescription_id_UNIQUE` (`rxid` ASC) VISIBLE,
INDEX `fk_prescription_patient2_idx` (`patient_ssn` ASC) VISIBLE,
INDEX `fk_prescription_pharmacy1_idx` (`pharmacy_id` ASC) VISIBLE,
CONSTRAINT `fk_prescription_doctor1`
FOREIGN KEY (`doctor_ssn`)
REFERENCES `project1`.`doctor` (`ssn`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_prescription_patient2`
FOREIGN KEY (`patient_ssn`)
REFERENCES `project1`.`patient` (`ssn`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_prescription_pharmacy1`
FOREIGN KEY (`pharmacy_id`)
REFERENCES `project1`.`pharmacy` (`pharmacy_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`pharma_comp`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`pharma_comp` (
`pharma_comp_id` INT NOT NULL AUTO_INCREMENT,
`phone_num` INT NOT NULL,
`pharma_comp_name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`pharma_comp_id`),
UNIQUE INDEX `pharma_comp_id_UNIQUE` (`pharma_comp_id` ASC) VISIBLE,
UNIQUE INDEX `pharma_comp_name_UNIQUE` (`pharma_comp_name` ASC) VISIBLE)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`drug`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`drug` (
Team 18 Project Report - CST363
8
`drug_id` INT(11) NOT NULL,
`formula` VARCHAR(200) NOT NULL,
`pharma_comp_id` INT NULL DEFAULT NULL,
`trade_name` VARCHAR(100) NOT NULL,
`price` DECIMAL(7,2) NOT NULL,
PRIMARY KEY (`drug_id`),
UNIQUE INDEX `drug_id_UNIQUE` (`drug_id` ASC) VISIBLE,
INDEX `fk_drug_pharma_comp1_idx` (`pharma_comp_id` ASC) VISIBLE,
CONSTRAINT `fk_drug_pharma_comp1`
FOREIGN KEY (`pharma_comp_id`)
REFERENCES `project1`.`pharma_comp` (`pharma_comp_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`drug_listing`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`drug_listing` (
`drug_listing_id` INT NOT NULL AUTO_INCREMENT,
`drug_id` INT NOT NULL,
`pharmacy_id` INT NOT NULL,
`price` DECIMAL(7,2) NOT NULL,
PRIMARY KEY (`drug_listing_id`),
UNIQUE INDEX `drug_listing_id_UNIQUE` (`drug_listing_id` ASC) VISIBLE,
INDEX `fk_drug_listing_pharmacy1_idx` (`pharmacy_id` ASC) VISIBLE,
INDEX `fk_drug_listing_drug1_idx` (`drug_id` ASC) VISIBLE,
CONSTRAINT `fk_drug_listing_pharmacy1`
FOREIGN KEY (`pharmacy_id`)
REFERENCES `project1`.`pharmacy` (`pharmacy_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_drug_listing_drug1`
FOREIGN KEY (`drug_id`)
REFERENCES `project1`.`drug` (`drug_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`supervisor`
Team 18 Project Report - CST363
9
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`supervisor` (
`supervisor_id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NOT NULL,
`phone_num` INT NOT NULL,
`pharmacy_id` INT NOT NULL,
PRIMARY KEY (`supervisor_id`),
UNIQUE INDEX `supervisor_id_UNIQUE` (`supervisor_id` ASC) VISIBLE)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `project1`.`contract`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `project1`.`contract` (
`contract_id` INT NOT NULL AUTO_INCREMENT,
`pharmacy_id` INT NOT NULL,
`pharma_comp_id` INT NOT NULL,
`start_date` DATE NOT NULL,
`end_date` DATE NULL,
`contract_text` VARCHAR(45) NOT NULL,
`supervisor_id` INT NOT NULL,
PRIMARY KEY (`contract_id`),
UNIQUE INDEX `contract_id_UNIQUE` (`contract_id` ASC) VISIBLE,
INDEX `fk_contract_pharmacy1_idx` (`pharmacy_id` ASC) VISIBLE,
INDEX `fk_contract_pharma_comp1_idx` (`pharma_comp_id` ASC) VISIBLE,
INDEX `fk_contract_supervisor1_idx` (`supervisor_id` ASC) VISIBLE,
CONSTRAINT `fk_contract_pharmacy1`
FOREIGN KEY (`pharmacy_id`)
REFERENCES `project1`.`pharmacy` (`pharmacy_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_contract_pharma_comp1`
FOREIGN KEY (`pharma_comp_id`)
REFERENCES `project1`.`pharma_comp` (`pharma_comp_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_contract_supervisor1`
FOREIGN KEY (`supervisor_id`)
REFERENCES `project1`.`supervisor` (`supervisor_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Team 18 Project Report - CST363
10

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

Queries

-- 1. Display all patients' names whose prescriptions have been fulfilled from "Walgreens",
sorted alphabetically.
SELECT DISTINCT patient.name FROM patient
INNER JOIN prescription ON patient.patient_id =
prescription.patient_id
INNER JOIN transaction ON prescription.prescription_id =
transaction.prescription_id
INNER JOIN pharmacy ON transaction.pharmacy_id = pharmacy.pharmacy_id
WHERE pharmacy_name = "Walgreens" ORDER BY patient.name;

-- 2. Display all drug names and their generic formulas that are under supervisions by their
contract's supervisor with phone number 1234567890. This query is to be used when a
company wants to know the drugs' contracts that are being supervised by a specified (via
phone number) supervisor.
SELECT drug.drug_name, drug.generic_formula, supervisor.name FROM drug
INNER JOIN contract ON drug.pharma_comp_id = contract.pharma_comp_id
INNER JOIN supervisor ON contract.supervisor_id =
supervisor.supervisor_id
WHERE supervisor.phone_num = 1234567890;

-- 3. Display all drug names and each of their total quantities fulfilled.
SELECT drug.drug_name, SUM(prescription.quantity) AS quantity_fulfilled
FROM drug INNER JOIN prescription ON prescription.drug_id =
drug.drug_id
INNER JOIN transaction ON prescription.prescription_id =
transaction.prescription_id
GROUP BY drug.drug_id;

-- 4. Display the names of all doctors and patients without repeating names of doctors who are
also patients.The query would be useful for a company that wants a list of everyone in their
network, both doctors and patients.
SELECT name FROM patient
Team 18 Project Report - CST363
11
UNION
SELECT name FROM doctor
ORDER BY name;

-- 5. Display the drug name and its average price for each drug among all pharmacies.
SELECT drug.drug_name, AVG(drug_listing.price) FROM drug
INNER JOIN drug_listing ON drug.drug_id = drug_listing.drug_id
GROUP BY drug.drug_id;

-- 6. Check if the drug "advil" is sold in any pharmacy in Los Angeles.


SELECT EXISTS(
SELECT drug_listing.drug_id FROM drug_listing
INNER JOIN drug ON drug_listing.drug_id = drug.drug_id
INNER JOIN pharmacy ON drug_listing.pharmacy_id =
pharmacy.pharmacy_id
WHERE drug.drug_name = 'advil' AND pharmacy.city =
'Los Angeles'
) AS result;
Team 18 Project Report - CST363
12
newPatient() Testing:

newPatient() method - “Pediatrics” PCP selection with non-child patient:

newPatient() method - “Orthopedics” PCP selection:


Team 18 Project Report - CST363
13
newPatient() method - too short SSN:

newPatient() method - invalid birth year - out of 1900-2022 range:


Team 18 Project Report - CST363
14
newPatient() method - invalid city - only contains blank space:

newPatient() method - invalid name - number present:


Team 18 Project Report - CST363
15
newPatient() method - invalid SSN - 00 middle two digits:

newPatient() method - invalid SSN - too long:


Team 18 Project Report - CST363
16
newPatient() method - invalid state - more than 3 characters:

newPatient() method - invalid street - no letters present:


Team 18 Project Report - CST363
17
newPatient() method - invalid zip code - not only numbers:

newPatient() method - XSS prevention sanitation test:


Team 18 Project Report - CST363
18
newPatient() method - successful registration:
Team 18 Project Report - CST363
19

FDA Report Testing:

Successful run with passing validations:

Semi-successful run, validation flags raised but allowed user to correct:

Manager Report
Team 18 Project Report - CST363
20
Team 18 Project Report - CST363
21
Prescription Fill Testing:
Successful run:

Run invalid patient name:


Team 18 Project Report - CST363
22

Run with invalid RXID:

Run with invalid Pharmacy address:


Team 18 Project Report - CST363
23
Run with RXID not existing:
Team 18 Project Report - CST363
24
Conclusions

We learned in part one that defining foreign keys, composite keys, and surrogate keys versus natural
keys can be a complex process. It can be difficult to foresee issues with using natural keys, and
difficult to predict when using a surrogate key would have issues. We also learned how to ensure that
normalization is much easier to ensure when using a top-down approach using ER diagram design.
We learned that client requirements necessitate that we as consultants be stringent as possible to
cover every possible false assumption and miscommunication when translating to the database
design. This initial part also highlighted the importance of being able to communicate clearly with
potential clients and ensure that as developers we have understanding of what a client's needs are.
Oftentimes, a client will provide vague descriptions of what they will want and we have to use some
intuition mixed with creativity to come up with a deliverable. Lastly, this assignment helped reinforce
some of the database concepts covered in the first couple weeks of the course.

You might also like