Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have designed the following database for a small project. Please review and leave feedback. The main problem I'm having is to keep tracking of many statuses. The user wants to know the status of particular action on a given date. Do I have to create seperate table for just statuses with date added, date modified etc?

Database structure

share|improve this question
"status"? Of what? Do you mean "ptApproachStatus", "drApproachStatus", etc. in the PatientsSet table? – radarbob Mar 17 '12 at 23:44
'best' practice I believe states to use singular table names. And what's the point of appending Set to the table names? Create just a general Address table, and then cross-reference tables as necessary. Potentially create a Person table, that has things like 'name' in it, then cross-reference for specifics. – Clockwork-Muse Apr 16 '12 at 16:48
1  
@X-Zero: table names should be plural, since it represents a set (which by definition can have more than 1 item). – Jeroen Jul 31 '12 at 8:40
@Jeroen - While tables do have more than one entity, it's not the set that's being represented; rather it's the (usually singular) entity itself (the individual row). This becomes more obvious with Entity Modeling, especially if the same model is used for generating both the database tables and the in-program data-structures. – Clockwork-Muse Jul 31 '12 at 15:43
@X-Zero: If I'm not mistaken, wars have been fought about this subject (don't know who won). – Jeroen Jul 31 '12 at 17:27
show 1 more comment

6 Answers

Considering our future requirements I would like to have a good domain model.

But if you observe the current design I'm not able to keep track of dates and history.

Would you mind pointing to specific entity how I can improve it ? Like create a separate table for statuses ?

I just realized I posted with different account, now its grabbing the account from Stackoverflow. Sorry for confusion.

share|improve this answer

If you break out the status table you could add an table that defines how states transition from one state to the next.

This data would be used to encode rules like "you can't have a FinalConsentStatus without a PtApproachStatusYes". Without this you must encode each rule in your source code and any change to the rules require a redeployment. There are however new problems like what happens to changes to transitions that are "in flight"

                                                        TransitionHistory
                                 Transition             +--------------+
                                 +------------+-------->|ID            |
                                 |ID          +         |--------------|
                                 |------------|         |PatientsetID  |
                                 |Name        |         |TransitionID  |
         State    +------------->|FromState   |         +--------------+
         +--------+------------->|ToState     |
         | ID     +              +------------+
         |--------|
         | Name   |
         +--------+
share|improve this answer

I would recommend separating the patient transactions from the patient profile, I think this is the status, into separate table.

Depending on the business, you want to look at it as a transaction, which has different updates, including letter sending, phone followups etc, multiple status values from which you can get a current status along with a history of what was done.

share|improve this answer
+1 for separating patient profile from status. Otherwise tracking patient status history is not possible. – radarbob Mar 17 '12 at 23:32
  1. No need to end the word with Set. Everyone knows it's a set.

  2. Using singular names for tables makes more sense when you are using an ORM (Doctor doctor = new Doctor())

  3. Doctors, patients, and Hospital Organizations are all legal persons (Party Model).

  4. Doctors can be patients and vice versa

    Party -< Roles {doctor, patient}

  5. An Address is its own type. A hospital has 1+ addresses (or 1 address with many buildings). A doctor has 1+ addresses (home, office, cottage). A patient has 1+ addresses. These addressPlacements can change over time too.

    Party -< PartyAddress >- Address

  6. A patient has many symptoms, visits, diagnoses, treatments, etc.

  7. To track a status over time i would go with something like this:

    SomePatientStatus
    patientId int references Patient
    somePatientStatusTypeId int references SomePatientStatusType
    created datetime

share|improve this answer

How I would lay things out is below. This will normalize the information being saves. There is only one table for information about people, no matter if a patient or a doctor. There is only one table to hold addresses, no matter for patient, doctor, or hospital.

The layout allows for any number of statuses, and keeps a running history in the PatientStatus table - just never update or remove, only add new entries. New status types can be added at any point by adding a new entry in the Statuses table - any number no limit.

People
------
Id
Title
FirstName
MiddleName
LastName
OtherName
Gender
DateOfBirth


Addresses
---------
Id
Type
Line1
Line2
City
State
Zip
Country


PersonAddresses
---------------
Id
PersonId
AddressId


Phones
------
Id
Type
Number
Ext


PersonPhones
------------
Id
PersonId
PhoneId


Emails
------
Id
Type
Address


PersonEmails
------------
Id
PersonId
EmailIs


Hospitals
---------
Id
Name


HospitalAddresses
-----------------
Id
HospitalId
AddressId


Doctors
-------
Id
PersonId
HospitalId


Patients
--------
Id
PersonId
DoctorId


Statuses
--------
Id
Name


PatientStatuses
---------------
PatientId
StatusId
EntryDate


Letters
-------
Id
Name


PatientLetters
--------------
Id
PatientId
LetterId
EntryDate
ResponseDate
ResponseReceived

Some example queries:

List All Doctors
----------------
SELECT P.* FROM Doctors AS D INNER JOIN People AS P ON D.PersonId = P.Id


List All Doctors at a given Hospital
------------------------------------
SELECT P.* FROM Doctors AS D INNER JOIN People AS P ON D.PersonId = P.Id
                             INNER JOIN Hospitals AS H on D.HospitalId = H.Id
WHERE H.Name='ABC Hospital Inc.'


List Current Patient Statuses
-----------------------------
SELECT P.*, S.Name, PatS.EntryDate FROM Patients AS Pat
                              INNER JOIN People AS P ON Pat.PersonId.Id = P.Id
                              INNER JOIN PatientStatuses AS PatS ON PatS.PatientId = Pat.Id
                              INNER JOIN Statuses AS S ON PatS.StatusId = S.Id
ORDER BY PatS.EntryDate DESC
share|improve this answer

If you ever want to add more statuses, you'll probably want to have a flexible structure. If you're 100% sure you'll never need more statuses, a denormalized design is just as good as a normalized one.

Although, if you want to have a nice domain model with current state and history etc - possibly using an ORM with inheritance and behavior for states - you have to go with a normalized structure.

share|improve this answer
-1. He's asking about a more flexible way to handle status and this answer simply mimics the question. – radarbob Mar 17 '12 at 23:31
No, I say that if there's ever only one status, he doesn't need another table, if there's gonna be many (history) he needs another table. Thanks for being constructive. – Lars-Erik Mar 19 '12 at 8:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.