数据库设计 - 如何处理条件数据
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_id
和 vaccine_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 的条目。
原因:
明天您可能决定添加一种新疫苗,而现在标记为已接种所有疫苗的所有患者的结果都将被破坏。你会忘记他们没有接种新添加的疫苗。
这似乎是
我的情况:
考虑这两个 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_id
和 vaccine_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 的条目。
原因: 明天您可能决定添加一种新疫苗,而现在标记为已接种所有疫苗的所有患者的结果都将被破坏。你会忘记他们没有接种新添加的疫苗。