Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

1

Project 2 Database Report


February 02, 2021
Bablu Banik, Javier Gonzalez

Introduction

Our new technology consulting company, LA Valley Tech, has been asked to
develop a relational database for our newest client: the up-and-coming drug store chain,
City Rx. According to our client, they want us to create a relational database that will
store pertinent information for their expanding business. At LA Valley Tech we are
looking to improve upon our database designs and creations, and gain invaluable
experience by producing high-quality professionally crafted products and deliverables.
At the end of the day, we want to create databases that are intuitive, user-friendly, and
tailored to our client’s needs. Furthermore, the immediate goals for this project are as
follows:

❖ Provide meaningful information useful to the client


❖ Follow industry standards, conventions, and best practices
❖ Maintain data integrity to ensure that values are valid and error-free
❖ Avoid redundant data to make our designs more efficient
❖ Create a database that is easy to modify and expand
❖ Exceed our clients expectations by providing an exceptional product
❖ Learn and grow as a company and group

The proposed database will store patient and doctor PII (Personally Identifiable
Information), their corresponding relationships, and important prescription drug data
such as trade name, formula, and distributor. Our client would also like us to keep track
of other business analytics such as prescription drug prices at their various pharmacies
located around the city, the distributor or pharmaceutical company that sells the drugs,
the contract information between pharmaceutical companies and pharmacies, and
supervisors that oversee these contracts for each pharmacy. All of this stored data and
corresponding metadata will allow City Rx to keep track of their confidential patient and
doctor information, patient prescriptions filled, important drug and distributor information,
and overall sales from varying drug prices at their pharmacies. Collecting this
information will ensure that City Rx continues to grow as a drug store chain and allow
them to retain that competitive edge over the competition.
2
ER model

The proposed ER diagram above demonstrates the entities and relationships of


our design per the requirements and specifications given to us by our client and
gathered from our initial Business Process Analysis (BPA) of the company. Many factors
had to be taken into account in order to maximize database efficiency and performance.
We wanted to make sure that we minimized redundancy but allowed for fast data
retrieval. To satisfy all these requirements and design preferences, we ultimately settled
on implementing 10 different relational tables for our ER diagram:
3
1. Patients
2. DoctorsInfo
3. PharmaceuticalCompany
4. Drugs
5. Pharmacy
6. PrimaryDoctor
7. Price
8. Prescription
9. Supervisors
10. Contracts

Each table serves a very specific purpose and houses important information about the
entity indicated in the relation’s title.

During our initial research and BPA of City Rx, we discovered the following
information:

➢ Each patient has an identifying SSN, plus a name, age, and address.

➢ Doctors also have an identifying SSN. Additionally, each doctor has a


name, a specialty, and a number of years of experience.

The relational tables Patients and DoctorsInfo both consist of PII such as Social
Security Number (SSN), name, and age. Although SSN is a unique attribute for both the
Patients and DoctorsInfo tables, we want to make sure that this vital piece of personal
data is secure and kept confidential to prevent it from falling into the wrong hands.
Therefore, patientID and DoctorID attributes have been chosen as primary keys for their
respective tables. We also chose to add additional attributes to each table to provide the
end-user as much information as possible. Both tables have a first and last name
attribute (Fname, Lname) and each aforementioned table houses their own unique
attributes as well. Patients include age, address, city, State, and zipCode while
DoctorsInfo contains attributes for their medical specialty and date the doctor started
their medical practice, ExperienceStartDate.

Due to the normal doctor-patient relationship and interaction, we concluded that


every patient has a primary physician and every doctor has at least one patient. This
leads to a one-to-many (1:M) relationship between the doctor and patient relations. We
also included a PrimaryDoctor table that includes the primary key PrimaryDoctorID,
along with two foreign key attributes, DoctorID and patientID, that link the PrimaryDoctor
table with the DoctorsInfo and Patients tables respectively. We opted to include this
additional table because if you think about the traditional doctor-patient relationship,
every patient is assigned to a primary care physician and in the event they need to see
a specialty doctor, they have to first consult and get a referral from their primary care
4
doctor before seeing a specialist. The relationship between the Patient and
PrimaryDoctor entities is 1:M because a primary care doctor can have many patients,
but a patient can only have one primary care doctor. For the DoctorsInfo and
PrimaryDoctor tables, the 1:M relationship applies to these two entities as well. A
primary doctor can refer a patient to a specialty doctor, but a specialty doctor can be
referred by multiple primary doctors.

City Rx acquires its prescription drugs from various pharmaceutical companies


and provides some of their trademark drugs at many of their pharmacies. After
gathering more information from the client, we discovered:

➢ Each pharmaceutical company is identified by name and has a phone number.

➢ Each drug has a trade name and a formula. Each drug is sold by a given
pharmaceutical company, and the trade name identifies a drug uniquely from
among the products of that company. If a pharmaceutical company is deleted,
you need not keep track of its products any longer.

The tables PharmaceuticalCompany and Drugs share a 1:M relationship because a


pharmaceutical company can make many drugs, but a particular drug can only be made
from one pharmaceutical company. These two relations are bound by the primary key -
foreign key referenced by the attribute pharmID in both tables. Although pharmaceutical
companies are identified by name and phone number, we wanted to provide a unique ID
number attribute for this table as well. Just in case the name ever changes, the
pharmaID would always stay the same. For the Drugs table we included the trade name
of the drug and its patented formula. Furthermore, we assigned a primary key attribute
of drugID to this relation for the same reason that we assigned an ID number to the
PharmaceuticalCompany table: names change but ID numbers stay the same!

Now we’ll take a closer look at how the PPP or Price, Pharmacy, and Prescription
relations tie into our database design for City Rx’s business model. First off, it’s worth
mentioning that:

➢ Each pharmacy sells several drugs and has a price for each. A drug could be
sold at several pharmacies, and the price could vary from one pharmacy to
another.

In order to get the price of each drug from a particular pharmacy, we’ll have to join the
Drugs and Price table by the former’s primary key, drugID. Because a many-to-many
(M:N) relationship exists between the Drugs and Pharmacy tables, the Price table was
created to act as a linking table or bridge relation between these two relations. Between
the Drug and Price tables there exists a 1:M relationship because a drug can have
many prices (depending on the pharmacy) but the set price of a drug can only be
assigned to one drug. This Price table also consists of another foreign key,
5
PharmacyID, that will link the Price table to the Pharmacy table. The Price table also
tracks the price (priceAmount) of each drug sold at a particular pharmacy. A check
constraint was added for the priceAmount attribute to make sure that the priceAmount >
0. This is to ensure that a valid price amount is entered in the Price table. The Price and
Pharmacy tables share a 1:M relationship because a pharmacy can have one set drug
price but there can be varying drug prices at a pharmacy. Lastly, our Pharmacy relation
includes all the identifiable information (name, address, phone number, etc.) necessary
to distinguish it from other pharmacies.

The Prescription table at the top of our ER diagram plays an integral role in our
relational database design for our client. Not only does it link to the Pharmacy table but
it also links back to our Patients, DoctorsInfo, and Drugs tables. These four former
tables can all be mapped to the Prescription table via a 1:M relationship:

1. A pharmacy can fill multiple prescriptions but a prescription can only be filled by
one pharmacy.

2. A doctor can prescribe one or more prescriptions but a prescription can only be
prescribed by one doctor.

3. A patient can obtain multiple prescriptions but a prescription can only be obtained
by one patient.

4. A prescription can be written for one or many drugs but a particular drug can only
be written on one prescription.

Another important thing to keep in mind is that when a prescription is filled, we want to
make sure that we track the pharmacy that filled it, along with the date it was filled. The
Pharmacy and Prescription tables have to then be mapped by a primary-foreign key
relationship. This is accomplished by the attribute PharmacyID in both tables. A similar
process for connecting the DoctorInfo and Patients tables to Prescription is carried out
in the same fashion. The Prescription table is linked to the DoctorInfo table by its foreign
key, DoctorID, that corresponds to the primary key of the same name in the DoctorInfo
relation. The attribute patientID in both the Patients and Prescription tables is used to
map these two tables' relationship. Lastly, the Drugs and Prescription relations are
linked by their respective primary and foreign key, drugID.

The Prescription table also houses some very important data pertaining to the
prescription information of our client’s customers. It’s also worth noting that for each of
the patient’s prescriptions there is a date and quantity associated with it and this bit of
information is reflected in the attributes OrderDate and quantity. A check constraint was
added to the quantity attribute to make sure that the quantity entered is greater than 0.
The DateOrderFilled attribute is used to determine the date when the prescription was
6
filled. The attribute orderFilled takes one of two values, 0 or 1. If the value is 0 then the
order has not been filled and if it’s set to 1 then the prescription order was filled. Also,
the orderFilled attribute has a default value set to 0 and an added check constraint to
ensure that only the binary values of 0 or 1 can be entered for this attribute.

Our client also expressed a desire to monitor their contractual obligations with
their pharmaceutical partners and to track the supervisors that are appointed to each
contract. We were provided the following information from the client:

➢ Pharmaceutical companies have long-term contracts with pharmacies. A


pharmaceutical company can contract with several pharmacies, and a pharmacy
can contract with several pharmaceutical companies. For each contract, you
have to store a start date, an end date, and the text of the contract.

➢ Pharmacies appoint a supervisor for each contract. There must always be a


supervisor for each contract, but the contract supervisor can change over the
lifetime of the contract.

With this bit of information we created two additional tables, Contracts and Supervisors.
We can see a 1:M relationship between the PharmaceuticalCompany and Contracts
tables. A pharmaceutical company can hold up to several contracts with various
pharmacies but there can only be one contract held by a particular pharmaceutical
company and pharmacy. The relationship between Contracts and Supervisors is strictly
one-to-one (1:1). There is only one supervisor that supervises a contract and a contract
is supervised by only one supervisor. The Contracts relation is connected to the
PharmaceuticalCompany primary key by its foreign key of the same name, pharmID.
The attribute supervisorID is the referenced key that ties the Contracts table to the
Supervisors table. Both tables are assigned unique ID numbers that take the place of
their table’s primary key in the form of contractID and supervisorID. Not only does the
Contracts table contain the foreign keys pharmID and supervisorID, it also holds the
attributes StartDate and EndDate which indicate the dates that the contract is in effect.
The Contracts relation also stores the attribute for the text or language of each contract,
contractText. This contractText is left up to the client to input. As of now, we’ve left each
contractText field as 'some text' and it can be populated up to 500 characters. The
Supervisor table consists of the following attributes:

● supervisorID
● Fname
● Lname
● employmentStartDate
● employmentEndDate
● Active
7
The Active attribute takes one of two values, 0 or 1. A value of 0 indicates that the
supervisor is inactive but if it is set to 1 then the supervisor is active in his/her role at the
pharmacy. We also set a default value of 0 for this attribute and added a check
constraint to ensure that only the binary values of 0 or 1 can be entered for Active.

Relational schema derived from the ER model

The relational schema for our database design was created using CREATE
TABLE statements and its relational tables were created in the following order:

1. Patients
2. DoctorsInfo
3. PharmaceuticalCompany
4. Drugs
5. Pharmacy
6. PrimaryDoctor
7. Price
8. Prescription
9. Supervisors
10. Contracts

The order in which these relational tables were created was done intentionally. The
creation of these tables had to be ordered in such a way that the tables that had foreign
keys had to be created after the tables referenced by the foreign keys. For example, we
had to create the relations Patients and DoctorInfo before we could create the relation
PrimaryDoctor, because foreign keys in PrimaryDoctor refer to the primary keys of the
relations Patients and DoctorInfo. If we created the PrimaryDoctor table before the
Patients and DoctorInfo tables it would have violated the referential integrity constraint
rule. For the sake of conciseness, we’ve chosen to demonstrate our CREATE TABLE
statement for the Prescription relational table below:
8
The rest of the CREATE TABLE statements for the additional relational tables can be
found in our attached SQL file accompanying this report.

Normalized relational schema

Although we are confident that our model adheres to an efficient and effective
design, we are aware that this is an ongoing project and adjustments may have to be
made to improve the normalization process to maximize efficiency and overall database
performance. In order to make our database more user-friendly and intuitive, we
decided to normalize our design to comply with the Third Normal Form (3NF). Achieving
a normalized design was accomplished by removing any partial or transitive functional
dependencies and because most of our relational tables have single-column primary
keys, we didn’t run into any issues of partial functional dependency. Only the Price table
has a composite primary key but it relies on full key functional dependency and is
already in a normalized form. Fortunately, none of our non-key attributes in our relations
determine other non-key attributes in the same relation and therefore, no transitive
functional dependencies exist in any of our tables.
Having a normalized relational schema allows for optimal database design by
reducing redundant data and makes the database less prone to update anomalies.
Eliminating redundant data will allow the client to update information in their database
without fear of corrupting data and creating inconsistencies in the relational tables. This
will ensure that if data has to be updated, it will only have to be altered in one location,
as opposed to multiple locations in other relational tables, which can lead to unforeseen
errors and negatively affect our client’s business.

SQL queries

To demonstrate the versatility of our relational database design, we’ve included 5


sample SQL statement queries that illustrate some common data retrievals that could
be implemented by our database:

-- 1. What are the total sales per pharmacy?

Display PharmacyID, name and total amount of sales as TotalSales


SELECT ph.PharmacyID, ph.name, sum(p.priceAmount * pr.quantity) as TotalSales
FROM Pharmacy ph
JOIN Price p ON p.PharmacyID = ph.PharmacyID
JOIN Prescription pr ON pr.PharmacyID = ph.PharmacyID
GROUP BY ph.PharmacyID, ph.name;
9
-- 2. What is the total number of patients for doctors with patients?

Display doctor’s name and their total number of patients


SELECT d.Fname, d.Lname, COUNT(p.patientID) AS numberOfPatients
FROM DoctorsInfo d
JOIN PrimaryDoctor pd ON d.DoctorID = pd.DoctorID
JOIN Patients p ON p.patientID = pd.patientID
GROUP BY d.DoctorID;
ORDER BY numberOfPatients DESC;

-- 3. How many Pharmaceutical Companies have at least 2 contracts?

Display the pharmID , Name and number of contracts for the Pharmaceutical Company
with at least 2 contracts

SELECT p.pharmID, p.Name , COUNT(*) AS NumberOfContracts


FROM PharmaceuticalCompany p
JOIN Contracts c ON c.pharmID = p.pharmID
GROUP BY p.pharmID, p.Name
HAVING NumberOfContracts >= 2
ORDER BY NumberOfContracts DESC;

-- 4 Which drugs are priced above the average price for all drugs sold?

Display the drugID, name as DrugName, name as PharmacyName and priceAmount for
drugs whose price is above the average price of all drugs sorted by drugID.
SELECT d.drugID, d.name AS DrugName, ph.name AS PharmacyName, priceAmount
FROM Drugs d
JOIN Price p ON p.drugID = d.drugID
JOIN Pharmacy ph ON ph.PharmacyID = p.PharmacyID
WHERE priceAmount > (SELECT AVG(priceAmount)
FROM Price)
ORDER BY d.drugID;

-- 5. How many drugs does each Pharmaceutical Company sell?

Display the pharmID , Name and number of drugs sold by each Pharmaceutical
Company. Sort from highest to lowest number of drugs sold
SELECT p.pharmID, p.Name, COUNT(d.pharmID) AS DrugsSold
FROM PharmaceuticalCompany p
JOIN Drugs d ON d.pharmID = p.pharmID
GROUP BY p.pharmID, p.Name
ORDER BY DrugsSold DESC;
10
Conclusions

At the start of this project we set out to accomplish some goals for this task and
we feel that we met and exceeded every one of them. From the initial requirements
presented to us by the client to the added information gathered from our analysis, our
relational tables, ER model, schema, and sample SQL queries reflect all the hardwork
and dedication put into this relational database design. This project allowed us to
expand our knowledge of relational database design principles, constructing ER
diagrams, deriving relational schemas from ER models, and the normalization process.
During this process, we had to go back to the drawing board many times and reference
our notes and reading materials to ensure that our database design was following
standards of best practice while fulfilling our duty to meet the client’s needs. After many
days of analysis, group meetings, brainstorming, and collaboration, we were able to
break down our client’s business model into a relational database design that we at LA
Valley Tech are extremely proud of and excited to present to our client, City Rx. As we
move into the next phase of this project, we are looking to expand and improve upon
our database design by making it easier to use, interactive, and intuitive for our end
users. Ultimately, we want to take what we created for this initial phase and bring it to
the next level. By doing so, it will not only improve our business but that of our
knowledge and understanding of the overall database design process.

Web Application and JDBC SQL

For the second part of this project, we took the normalized schema that we
designed for our client and created a Java web application using Spring Boot Controller
architecture. This web application consists of four parts and demonstrates how our
database design allows for prescriptions to be ordered and filled from the sample data
that we created. We also included a Pharmacy Drug Report to be used by Pharmacists
and a FDA Drug Report to monitor the quantity of drugs prescribed by each doctor.

Part 1: http://localhost:8080/prescription/new
This form allows doctors to write prescriptions for their patients. The doctors will
have to input their SSN and name, as well as their patients. They will also need to input
the drug name and its quantity.
Figure 1: New Prescription Written
11
Figure 2: Invalid Entry (Missing Doctor’s Name)

Part 2: http://localhost:8080/prescription/fill
Patients can fill out a form from the URL above to request that a prescription be
filled at a particular pharmacy. The patient will enter the prescription number, pharmacy
name, and address. If the drug is available at the pharmacy, the prescription will be
filled and will display the cost and date the order was filled.

Figure 3: New Prescription Filled

Figure 4: Drug Not Available At Pharmacy Figure 5: Invalid Rx#


12
Part 3: http://localhost:8080/pharmacy_form.html
A Pharmacist can request a Pharmacy Drug Report from a specific pharmacy
via an online form provided by the URL above. This report will include the name of the
drug and the quantity used. All the Pharmacist has to input is the Pharmacy ID and a
date range.

Figure 6: New Drug Report Requested

Figure 7: Invalid Pharmacy ID

Part 4: http://localhost:8080/fda_form.html
If an FDA government official is looking to generate a report for the quantity of
drugs that each doctor has prescribed for a set range of dates, he/she can fill out the
form found at the hyperlink above.
13
Figure 8: Valid FDA Drug Report

Figure 9: Invalid FDA Drug Report (Missing Drug Name)

You might also like