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:
| Keyword | Meaning | Example |
|---|---|---|
at least N | N or more values | has phone: at least 1 string |
between N M | Between N and M (inclusive) | has ref: between 2 5 Owner |
at most N | Between 0 and N (inclusive) | has parents: at most 2 Person |
exactly N | Exactly N values | has 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
| Syntax | Meaning | Example use case |
|---|---|---|
one Type | Exactly one (required) | has name: one string |
optional Type | Zero or one | has nickname: optional string |
Type | Any (0 to ∞, the default) | has tag: string |
at least N Type | N or more | has phone: at least 1 string |
at most N Type | 0 to N (inclusive) | has parents: at most 2 Person |
between N M Type | Between N and M (inclusive) | has references: between 2 5 Owner |
exactly N Type | Exactly N | has 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.