Consider the following business domain:
- An
Airline
has a unique airline id (aid
) and contains zero-or-morePlanes
. - A
Plane
has a unique plane id (pid
) in theAirline
it flies for (but planes from differentAirlines
can have overlappingids
). - Each
Plane
has one-or-moreSeats
. - A
Seat
has a unique seat id (sid
) in its plane (butSeats
from differentPlanes
may have overlappingids
).
My attempt so far
Here is my attempt at solving this:
CREATE SEQUENCE planes_seq;
CREATE TABLE Airlines (
aid INTEGER PRIMARY KEY DEFAULT nextval('planes_seq')
);
CREATE TABLE Planes (
aid INTEGER REFERENCES Airlines(aid)
, pid INTEGER
, PRIMARY KEY(aid, pid)
);
CREATE TABLE Seats (
aid INTEGER
, pid INTEGER
, sid INTEGER
, PRIMARY KEY(aid, pid, sid)
, FOREIGN KEY(aid, pid) REFERENCES Planes(aid, pid)
);
ALTER TABLE Planes ADD CONSTRAINT fk_seats FOREIGN KEY(aid, pid)
REFERENCES Seats(aid, pid);
However, it fails because the final ALTER TABLE
is illegal since the pair (Seats.aid, Seats.pid)
is indeed not unique.
Questions
- How could I enforce the "a plane has at least one seat" constraint?
- Is this scheme in 3rd Normal Form?
PS: I am new to SQL and this is a (small part) of a homework assignment. I have tried following the parent-with-at-least-one-child example from another DBA question (Constraint to enforce "at least one" or "exactly one" in a database) but there are way too many tricks there that I cannot understand (multiple WITH
queries, a RETURNING
clause and so on). It looks to me like there must be a simpler way to do it.