Question

I'm modelling a hierarchy of three entities for a therapy planning software. A therapy is basically understood as a number of medications that are given to a patient on a number of days. I want to be able to cancel therapy on any given day, in a write-only-once fashion (for quality control certification purposes).

Here's the concrete question: Is it ok to reuse a part of a composite foreign key as a another foreign key? In my case the composite key points from the medication table to the day table, which then points back to the therapy. The therapy id is included in the composite foreign key in the medication table, so I could use this as a foreign key, making querying more easy?

The table definitions should be something like this (modulo hickups in my raw SQL skills, I usually always employ some kind of ORM):

CREATE TABLE therapy (
    "id" INTEGER NOT NULL,
    "start" DATE NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE day (
    "therapy_id" INTEGER NOT NULL,
    "day" INTEGER NOT NULL,
    "revision" INTEGER NOT NULL,
    "comment" TEXT;
    "cancelled" BOOLEAN NOT NULL;
    PRIMARY KEY (therapy_id, day, revision),
FOREIGN KEY(therapy_id) REFERENCES therapy (id)
);

CREATE TABLE medication (
    "id" INTEGER NOT NULL,
    "therapy_id" INTEGER NOT NULL,
    "day" INTEGER NOT NULL,
    "revision" INTEGER NOT NULL,
    "substance" VARCHAR(100) NOT NULL,
    "dosage" VARCHAR(50) NOT NULL,
    PRIMARY KEY (id),
FOREIGN KEY(therapy_id, day, revision) REFERENCES day (therapy_id, day, revision),
-- wondering if this is ok
    FOREIGN KEY(therapy_id) REFERENCES therapy (id)
);

Please note that the relation from day to medication is one-to-many, e.g. on day 3 I want to plaster the patient with a deadly mix of Ibuprofen, Paracetamol, Aspirin, ground up coffee beans and a good shot of Jaegermeister.

Was it helpful?

Solution

Here's what you started with.

CREATE TABLE medication (
    "id" INTEGER NOT NULL,               -- You don't need this.
    "therapy_id" INTEGER NOT NULL,
    "day" INTEGER NOT NULL,
    "revision" INTEGER NOT NULL,
    "substance" VARCHAR(100),
    "dosage" VARCHAR(50),
    PRIMARY KEY (id),                    -- Drop this.
    FOREIGN KEY(therapy_id, day, revision) 
        REFERENCES day (therapy_id, day, revision),  -- Ok, but should be PK.
    FOREIGN KEY(therapy_id) REFERENCES therapy (id) -- You don't need this.
);

The column "id" serves no useful purpose, and has instead convinced you that you don't need a unique constraint on the real key: {therapy_id, day, revision}. Replace the useless primary key constraint on "id" with a primary key constraint on {therapy_id, day, revision}. Drop the last foreign key constraint. You know "therapy_id" will reference an existing row, because the foreign key constraint in the table "day" requires it.

That leaves us with this.

CREATE TABLE medication (
    "therapy_id" INTEGER NOT NULL,
    "day" INTEGER NOT NULL,
    "revision" INTEGER NOT NULL,
    "substance" VARCHAR(100),
    "dosage" VARCHAR(50),
    PRIMARY KEY (therapy_id, day, revision),
    FOREIGN KEY(therapy_id, day, revision) 
        REFERENCES day (therapy_id, day, revision)
);

It troubles me that "substance" and "dosage" are nullable. Think about that a little.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top