Tables whose sole purpose is specify a subset of another table

1k views Asked by At

The database I'm designing has an employees table; there can be multiple types of employees, one of which are medical employees. The database needs to also describe a many-to-many relation between medical employees and what competences they have.

Is it okay to create a table medical_employees with only an id column, whose only purpose is to specify which employees are medics? The id column has a foreign key constraint that references the employees table. The code below should make my question clearer:

/* Defines a generic employee */
CREATE TABLE employees (
    id      INT PRIMARY KEY AUTO_INCREMENT,
    name    VARCHAR(100) NOT NULL
);

/* Specifies which employees are medics */
CREATE TABLE medical_employees (
    id INT NOT NULL,
    FOREIGN KEY (id) references employees(id);
);

/* Specifies what competences a medic can have */
CREATE TABLE medical_competences (
    id     INT PRIMARY KEY AUTO_INCREMENT,
    name   VARCHAR(100) NOT NULL
);

/* A many-to-many relation between medical employees and
   their competences. */
CREATE TABLE medical_employees_competences (
    id             INT PRIMARY KEY AUTO_INCREMENT,
    medic_id       INT NOT NULL,
    competence_id  INT NOT NULL,
    FOREIGN KEY (medic_id) REFERENCES medical_employees(id),
    FOREIGN KEY (competence_id) REFERENCES medical_competences(id)
);
3

There are 3 answers

0
Rahul On

Why a separate table for that. Why not just create a BIT/Boolean field say IsMedical and set that to TRUE for medical employees in employee table like

/* Defines a generic employee */
CREATE TABLE employees (
    id      INT PRIMARY KEY AUTO_INCREMENT,
    name    VARCHAR(100) NOT NULL,
    IsMedical BIT(1)
);

That way, say if you want to get all medical employees from Employee table; you will just have to do a single filter in WHERE condition saying WHERE IsMedical = true. Whereas, if you go by a separate table then you will have perform a INNER JOIN with medical_employees and employees table which I believe would be more costly and unnecessary.

1
Bill Karwin On

+1 to answer from @Rahul, another alternative is to create an attribute in the employees table. Although I would not use BIT because there are bugs in that data type. Just use BOOLEAN or TINYINT.

But the way you have it, creating a second table, has the following advantage: the medical_employees_competences is implicitly restricted to reference only medical employees. It cannot reference someone unless they're in that table.

Another way to provide that constraint is to make the foreign key in the following way:

CREATE TABLE employees (
    id      INT PRIMARY KEY AUTO_INCREMENT,
    name    VARCHAR(100) NOT NULL
    IsMedical BOOLEAN DEFAULT 0,
    KEY (id, IsMedical)
);

/* A many-to-many relation between medical employees and
   their competences. */
CREATE TABLE medical_employees_competences (
    id             INT PRIMARY KEY AUTO_INCREMENT,
    IsMedical      BOOLEAN DEFAULT 1, /* only put 1 in this column */
    medic_id       INT NOT NULL,
    competence_id  INT NOT NULL,
    FOREIGN KEY (medic_id, IsMedical) REFERENCES medical_employees(id, IsMedical),
    FOREIGN KEY (competence_id) REFERENCES medical_competences(id)
);

Now you can achieve the same constraint, that you can only reference medical employees using the second table.

0
philipxy On

Yes it is ok, it is the straightforward relational idiom and it is what you should do. (You can search on SQL subtypes & supertypes.)

When one has disjoint subtyping, eg other kinds of employees where an employee can only be of one kind, there are SQL idioms for constraining that to be the case as declaratively as possible. This can involve a constant type discriminator column in the supertype describing which sole subtype its id should appear in. (The IDEF1X idiom.) There is also an idiom involving that type discriminator also in subtypes sometime avoidig further non-declarative constraints. For the former see (answer) How to Implement Referential Integrity in Subtypes. (Explaining the former although disparaging the latter.) For the latter see (conference paper) Foreign Superkeys and Constant References.