Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 6: How Many Vaccines?

Biscuit the golden retriever needed three vaccines: rabies, distemper, and bordetella. Dr. Portbridge tried has vaccine: one string, but that could only hold one value. She tried adding three separate fields, vaccine1, vaccine2, vaccine3, and immediately hated herself for it. What about animals that need five? Or none?


The problem

Sometimes an attribute holds more than one value. A single has vaccine: one string gives you exactly one. The real world isn’t that tidy.

Multi-valued cardinality

In the previous chapter, you learned one and optional. But Dolfin has richer cardinality keywords for multi-valued attributes:

KeywordMeaningExample
at least NN or more valueshas phone: at least 1 string
between N MBetween N and M (inclusive)has ref: between 2 5 Owner
at most NBetween 0 and N (inclusive)has parents: at most 2 Person
exactly NExactly N valueshas coord: exactly 3 float
(none)Any (0 to ∞)has tag: string

Combined with the keywords from Chapter 5, here’s the full cheat sheet:

Cardinality cheat sheet

SyntaxMeaningExample use case
one TypeExactly one (required)has name: one string
optional TypeZero or onehas nickname: optional string
TypeAny (0 to ∞, the default)has tag: string
at least N TypeN or morehas phone: at least 1 string
at most N Type0 to N (inclusive)has parents: at most 2 Person
between N M TypeBetween N and M (inclusive)has references: between 2 5 Owner
exactly N TypeExactly Nhas coordinates: exactly 3 float

Applying cardinality to the clinic

Let’s think about what needs multi-valued cardinality:

Animals can have multiple vaccines, and might have multiple allergies:


concept Animal:
  has name: one string
  has species: one Species
  has age: optional int
  has weight: optional float
  has owner: optional Owner
  has vaccines: string
  has allergies: string

Here vaccines and allergies use the default “any” that is zero or more strings, no upper limit.

Owners must have at least one phone number but could have several:


concept Owner:
  has first_name: one string
  has last_name: one string
  has phone_numbers: at least 1 string
  has email: optional string
  has address: optional string

Appointments might involve multiple treatments:


concept Appointment:
  has animal: one Animal
  has date: one string
  has reason: one string
  has urgency: one Urgency
  has status: one AppointmentStatus
  has diagnosis: optional string
  has treatments: string
  has notes: string

A concept for vaccines

Actually, a vaccine isn’t just a string. It has a name, a date administered, and a batch number. Let’s promote it to a concept:


concept Vaccination:
  has vaccine_name: one string
  has date_administered: one string
  has batch_number: optional string

concept Animal:
  has name: one string
  has species: one Species
  has age: optional int
  has weight: optional float
  has owner: optional Owner
  has vaccinations: Vaccination
  has allergies: string

Now each vaccination is a rich object, not just a name. And because vaccinations uses the default cardinality (“any”), an animal can have zero, one, or many vaccinations.

The story so far


package <http://happypaws.com/clinic>:
  dolfin_version "1"
  version "0.1.0"
  author "Dr. Helen Portbridge"
  description "The Happy Paws veterinary clinic data model"

concept Species:
  only values:
    Dog
    Cat
    Bird
    Rabbit
    Reptile
    Other

concept Urgency:
  only values:
    Routine
    Urgent
    Emergency

concept AppointmentStatus:
  only values:
    Scheduled
    InProgress
    Completed
    Cancelled

concept Owner:
  has first_name: one string
  has last_name: one string
  has phone_numbers: at least 1 string
  has email: optional string
  has address: optional string

concept Veterinarian:
  has name: one string
  has license_number: one string
  has specialization: optional string

concept Vaccination:
  has vaccine_name: one string
  has date_administered: one string
  has batch_number: optional string

concept Animal:
  has name: one string
  has species: one Species
  has age: optional int
  has weight: optional float
  has owner: optional Owner
  has vaccinations: Vaccination
  has allergies: string

concept Appointment:
  has animal: one Animal
  has date: one string
  has reason: one string
  has urgency: one Urgency
  has status: one AppointmentStatus
  has diagnosis: optional string
  has treatments: string
  has notes: optional string

property treatedBy:
  Animal -> Veterinarian

Try it

A Veterinarian can have multiple certifications (at least one) and speaks one or more languages. Add these attributes:


concept Veterinarian:
  has name: one string
  has license_number: one string
  has specialization: optional string

The vaccination records looked clean. Biscuit had three entries; Pixel had none yet. The system handled both gracefully.

But then a colleague, Dr. Reyes, joined the practice. He was a surgeon, not a general vet. And Dr. Portbridge realized her model treated every Veterinarian identically. She needed a way to say “a Surgeon is a Veterinarian, but with extra capabilities.” She needed inheritance.