0

我正在设计的数据库有一个employees表;可以有多种类型的员工,其中一种是医务人员。该数据库还需要描述医务人员之间的多对多关系以及他们拥有的能力。

是否可以创建一个medical_employees只有一id列的表,其唯一目的是指定哪些员工是医生?该id列具有引用该employees表的外键约束。下面的代码应该让我的问题更清楚:

/* 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)
);
4

3 回答 3

1

是的,没关系,这是直接的关系习语,这是你应该做的。(您可以搜索 SQL 子类型和超类型。)

当一个人有不相交的子类型时,例如其他类型的员工,其中一个员工只能是一种,有一些 SQL 惯用语可以尽可能地以声明方式约束这种情况。这可能涉及超类型中的常量类型鉴别器列,描述其 id 应出现在哪个唯一子类型中。(IDEF1X习惯用法。)有时在子类型中也有一个涉及该类型鉴别器的习惯用法,有时避免进一步的非声明性约束。对于前者,请参阅(答案)如何在子类型中实现参照完整性。(解释前者虽然贬低后者。)对于后者,请参阅(会议论文)Foreign Superkeys and Constant References

于 2014-11-28T07:27:24.717 回答
1

+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.

于 2014-11-27T21:12:48.330 回答
1

为什么要为此单独使用表格。为什么不直接创建一个BIT/Boolean字段说IsMedical并将其设置为表TRUE中的医务人员,employee例如

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

那样的话,假设你想让所有医务人员都离开Employee餐桌;你只需要在条件下做一个过滤器WHEREWHERE IsMedical = true。然而,如果您使用单独的表格,那么您将执行一个INNER JOINwith medical_employeesand employeestable,我认为这将更加昂贵和不必要。

于 2014-11-27T21:02:55.447 回答