数据库设计 - 如何处理条件数据

Database design - How to handle conditional data

这似乎是 的重复,但我已经检查过了,它没有回答我的问题。

我的情况:

考虑这两个 table:

patients                           |     vaccines                
                                   |
id | name     | birthdate          |     id | name
---------------------------        |     ---------------
1  | John Doe | 1994-03-12         |     1  | Tetanus
---------------------------        |     ---------------
2  | Jane Doe | 1996-80-02         |     2  | Hepatitis A

这个支点table

patient_vaccine

id | patient_id | vaccine_id | date_received | comment
----------------------------------------------------------------
1  | 1          | 1          | 2019-01-01    | Lorem ipsum dolor set
----------------------------------------------------------------
2  | 1          | 2          | 2019-01-12    | Lorem ipsum dolor set
----------------------------------------------------------------
3  | 2          | 1          | 2018-09-21    | Lorem ipsum dolor set

显然,要说特定患者接种了特定疫苗,将在具有 patient_idvaccine_id 的数据透视表 table 中插入新记录以及其他数据。

但我有一种情况,如果患者未满 18 岁,就不会有 vaccine_id,而是 took_all_vaccines布尔值。

我的问题:

什么被认为更好,将 18 岁以下患者的数据放在单独的 table 中,看起来像这样:

id | patient_id | took_all_vaccines | date_received | comment
----------------------------------------------------------------
1  | 1          | 1                 | 2019-01-01    | Lorem ipsum dolor set
----------------------------------------------------------------
2  | 1          | 0                 | 2019-01-12    | Lorem ipsum dolor set
----------------------------------------------------------------
3  | 2          | 9                 | 2018-09-21    | Lorem ipsum dolor set

或者我应该将 took_all_vaccines 列放在数据透视表 table 中并使其可为 null,对于 18 岁以上的人来说它为 null,这也需要 vaccine_id 列对于 18 岁以下的人可以为空。

所以我最终会得到这样的结果:

id | patient_id | vaccine_id | took_all_vaccines | date_received | comment
-----------------------------------------------------------------------------
1  | 1          | 1          | null              | 2019-01-01    | Lorem ipsum dolor set
-----------------------------------------------------------------------------
2  | 1          | 2          | null              | 2019-01-12    | Lorem ipsum dolor set
-----------------------------------------------------------------------------
3  | 2          | null       | 1                 | 2018-09-21    | Lorem ipsum dolor set

如果一个解决方案更好,为什么?为什么另一个不是?

您调用的 table 枢轴 table,在标准关系设计中通常称为多对多解析器 table。这是因为,在高层次上,您的设计涉及患者和疫苗之间的多对多关系。

  • 一个病人可以接种多种疫苗
  • 许多患者可以接种疫苗

现在回答您的具体问题:

这里没有完美的答案,因为这是存在于正常关系之外的业务规则,但我会做两种不同的事情之一。

关于疫苗的第一件事是 AFAIK,多种疫苗通常在一次注射中结合使用。因此,这需要 "shot" table 或疫苗 table 支持父子等级的能力。

"Took all vaccines" 在我看来是一种不具体且事实上不准确的陈述,但话又说回来我不知道你的申请。

鉴于此,我认为最简单和最好的答案是在疫苗中添加一行名为 "All Vaccines (Patient under 18 years of age)"。

那么您就不再需要担心 NULL 外键,这在多对多解决方案中肯定不希望如此 table。

另一种选择是实施注射容器 table(注射 1 -> 许多疫苗)并用 patient_shot 替换 patient_vaccine。您也可以通过将注射疫苗和疫苗合并到一个层次结构 table 中来做类似的事情,其中​​疫苗可以有一个父 "vaccine" 行。

我不会实施标志或添加 'Took all vaccines' 作为 patient_vaccine table 的条目。

原因: 明天您可能决定添加一种新疫苗,而现在标记为已接种所有疫苗的所有患者的结果都将被破坏。你会忘记他们没有接种新添加的疫苗。