You describe the system as a document management system. One solution then would be to honour the primacy of the documented nature of the entities in the system. The following model defines an abstract entity which acts as the parent for a table of documents and as the super-type for a bunch of sub-type tables. This model allows you to associate any number of documents with a DocumentedThing
.
DocumentedThing
---------------
ThingId Integer primary key
ThingType String check (ThingType in ('PUPIL', 'STAFF'))
unique key (ThingId, ThingType)
Document
--------
ThingId Integer foreign key references DocumentedThing (ThingId)
DocumentId Integer primary key
Text Clob
Pupil
-----
PupilId Integer primary key
ThingId Integer unique key
ThingType String check (ThingType = 'PUPIL')
Name String
DateOfBirth Date
foreign key (ThingId, ThingType)
references DocumentedThing (ThingId, ThingType)
Staff
-----
StaffId Integer primary key
ThingId Integer unique key
ThingType String check (ThingType = 'STAFF')
Name String
HireDate Date
foreign key (ThingId, ThingType)
references DocumentedThing (ThingId, ThingType)
The scaffolding of unique keys ensures that a DocumentedThing
can have a record in either Staff
or Pupil
but not both. Furthermore there cannot be multiple records in whichever sub-type table. A record in Staff
can only map to a record in DocumentedThing
which has a value of 'STAFF' in ThingType
. The one thing which is hard to enforce is the insistence that a DocumentedThing
must have a sub-type record. It can be done, but it is usually complicated, and to some extent depends on your choice of DBMS product.
Adding a new sub-type has a minimal impact: besides adding the actual table to hold its information you only need to add a new value to DocumentedThing.ThingType
; if you have a lot of sub-types you might choose to restrict this with a foreign key to a look-up table rather than a check constraint.