四个数据库表之间的多重关系的反规范化和减少冗余

Denormalization and reducing redundancy in multiple relationships among four database tables

我正在帮助一位社会科学家分析他的研究结果。他记录了数百次采访和其他会议,并收集了相关文件。他已将有关这项工作的数据输入到 MS Access 中的四个 table 中:

+---------+-----------+-----------------------------------------------------+
|  Table  |    Key    |                  Example contents                   |
+---------+-----------+-----------------------------------------------------+
| cases   | ID_Case   | Description, case data                              |
| persons | ID_Person | Name, contact data                                  |
| events  | ID_Event  | Date, time, location of interview, meeting, etc.    |
| files   | ID_File   | Path, filename, date of recordings, documents, etc. |
+---------+-----------+-----------------------------------------------------+

我们可以称它们为 "base" tables.

为了表示这些 table 之间的关系,他首先尝试了一组六个 table 链接到它们键上的原始四个:

+--------------+---------------------+
|    Table     |         Key         |
+--------------+---------------------+
| CasePersons  | ID_Case, ID_Person  |
| CaseEvents   | ID_Case, ID_Event   |
| CaseFiles    | ID_Case, ID_File    |
| EventPersons | ID_Event, ID_Person |
| EventFiles   | ID_Event, ID_File   |
| FilePersons  | ID_File, ID_Person  |
+--------------+---------------------+

我们可以称这些为 "binary relationship" tables.

示例场景(虚构)

这里是一个假想的场景来演示他的数据结构的例子。该场景涉及三个案例、七个人、三个事件和五个文件。

假设他对人们的爱情生活进行了两次采访。一个是对四个人的采访:乔治、莎莉、亨利和埃利奥特。第二次采访是对两个人的采访,John 和 Liz。第一次采访是视频录制的,第二次是音频录制的。第一次采访的一部分是单独录制的,只有 Sally 和 Henry。尽管 Liz 参加了第二次采访,但她没有说话,因此不在录音中。在第一次采访中,乔治分享了一封给莎莉的情书,扫描成 pdf 文件。最后,第三个活动是phone和同事开会,谈的是技术,没有讨论具体案例。

来自这个假想场景的数据显示在下面的 table 中。在每个 table 的名称旁边,我给出了数据库中实际 table 中的记录数。

四基Tables

Table [案例] (386 条记录)

+---------+---------------------------------+
| ID_Case |           Description           |
+---------+---------------------------------+
|       1 | A husband and wife are in love. |
|       2 | A man and woman are in love.    |
|       3 | A man has never been in love.   |
+---------+---------------------------------+

Table [人](1,472 条记录)

+-----------+-----------+----------+
| ID_Person | NameFirst | NameLast |
+-----------+-----------+----------+
|         1 | George    | Brown    |
|         2 | Sally     | White    |
|         3 | Henry     | Green    |
|         4 | John      | Baker    |
|         5 | Liz       | Jones    |
|         6 | Elliot    | Brooks   |
|         7 | Catherine | Drake    |
+-----------+-----------+----------+

Table [事件](526 条记录)

+----------+------------+---------------+
| ID_Event |    Date    |   Location    |
+----------+------------+---------------+
|        1 | 2016 06 01 | 123 Main St.  |
|        2 | 2016 07 02 | 456 Block Rd. |
|        3 | 2016 08 03 | Phone         |
+----------+------------+---------------+

Table [文件](1,748 条记录)

+---------+---------------------------+------+
| ID_File |         Filename          | Type |
+---------+---------------------------+------+
|       1 | Brown, Brooks interview   | avi  |
|       2 | White, Green subinterview | avi  |
|       3 | Brown letter              | pdf  |
|       4 | Baker interview           | wav  |
|       5 | Drake meeting             | wav  |
+---------+---------------------------+------+

六个二元关系Tables

在二元关系列表table中,我用相关文本替换了人物、事件和文件的键,以便于阅读。 MS Access 通过根据查询显示 table 字段来允许相同的行为。同样,某些 table 中显示的角色是数字外键的文本显示,用于分隔 table 允许的角色。

Table [CasePersons](720 条记录)

+---------+-----------+---------------+
| ID_Case | ID_Person |     Role      |
+---------+-----------+---------------+
|       1 | George    | Husband       |
|       1 | Sally     | Wife          |
|       1 | Henry     | Wife's friend |
|       2 | John      | Boyfriend     |
|       2 | Liz       | Girlfriend    |
|       3 | Elliot    | Individual    |
+---------+-----------+---------------+

Table [CaseEvents](299 条记录)

+---------+------------+
| ID_Case |  ID_Event  |
+---------+------------+
|       1 | 2016 06 01 |
|       2 | 2016 07 02 |
|       3 | 2016 06 01 |
+---------+------------+

Table [CaseFiles](301 条记录)

+---------+---------------------------+
| ID_Case |          ID_File          |
+---------+---------------------------+
|       1 | Brown, Brooks interview   |
|       1 | White, Green subinterview |
|       1 | Brown letter              |
|       2 | Baker interview           |
|       3 | Brown, Brooks interview   |
+---------+---------------------------+

Table [EventPersons](700 条记录)

+------------+-----------+-------------+
|  ID_Event  | ID_Person |    Role     |
+------------+-----------+-------------+
| 2016 06 01 | George    | Interviewed |
| 2016 06 01 | Sally     | Interviewed |
| 2016 06 01 | Henry     | Interviewed |
| 2016 06 01 | Elliot    | Interviewed |
| 2016 07 02 | John      | Interviewed |
| 2016 07 02 | Liz       | Present     |
| 2016 08 03 | Catherine | Present     |
+------------+-----------+-------------+

Table [事件文件](1,490 条记录)

+------------+---------------------------+-----------+
|  ID_Event  |          ID_File          |   Role    |
+------------+---------------------------+-----------+
| 2016 06 01 | Brown, Brooks interview   | Recording |
| 2016 06 01 | White, Green subinterview | Recording |
| 2016 06 01 | Brown letter              | Received  |
| 2016 07 02 | Baker interview           | Recording |
| 2016 08 03 | Drake meeting             | Recording |
+------------+---------------------------+-----------+

Table [FilePersons](2,392 条记录)

+---------------------------+-----------+-------------+
|          ID_File          | ID_Person |    Role     |
+---------------------------+-----------+-------------+
| Brown, Brooks interview   | George    | Interviewed |
| Brown, Brooks interview   | Sally     | Interviewed |
| Brown, Brooks interview   | Henry     | Interviewed |
| Brown, Brooks interview   | Elliot    | Interviewed |
| Brown letter              | George    | Writer      |
| Brown letter              | Sally     | Subject     |
| White, Green subinterview | Sally     | Interviewed |
| White, Green subinterview | Henry     | Interviewed |
| Baker interview           | John      | Interviewed |
| Drake meeting             | Catherine | Present     |
+---------------------------+-----------+-------------+

问题是在所有这些 table 中输入的数据有很多冗余。数百次采访,很容易出错,要么输入错误的某些数据,要么忘记输入所有六个二元关系 table 中的所有数据。一旦输入数据,就很难检查它们是否有错误。此外,冗余使得在数据中找到有意义的模式变得更加困难。

单身Four-Way关系Table

我一直在努力帮助他找出如何以更易于管理的方式表示这些数据。我一直在探索的一个想法是将六个二元关系 table 组合成一个具有四个关键字段的 table:ID_Case、ID_Person、ID_Event,以及 ID_File。那么上面的数据就变成了:

Table [CasePersonEventFiles] (??? 记录)

+---------+-----------+------------+---------------------------+-----------------+---------------+-------------+-------------+
| ID_Case | ID_Person |  ID_Event  |          ID_File          |     CP_Role     |    EP_Role    |   EF_Role   |   FP_Role   |
+---------+-----------+------------+---------------------------+-----------------+---------------+-------------+-------------+
|       1 | George    | 2016 06 01 | Brown, Brooks interview   | Husband         | Interviewed   | Recording   | Interviewed |
|       1 | Sally     | 2016 06 01 | Brown, Brooks interview   | Wife            | Interviewed   | * Recording | Interviewed |
|       1 | Henry     | 2016 06 01 | Brown, Brooks interview   | Wife's friend   | Interviewed   | * Recording | Interviewed |
|       1 | Sally     | 2016 06 01 | White, Green subinterview | * Wife          | * Interviewed | Recording   | Interviewed |
|       1 | Henry     | 2016 06 01 | White, Green subinterview | * Wife's friend | * Interviewed | * Recording | Interviewed |
|       1 | George    | 2016 06 01 | Brown letter              | * Husband       | * Interviewed | Received    | Writer      |
|       1 | Sally     | 2016 06 01 | Brown letter              | * Wife          | * Interviewed | * Received  | Subject     |
|       2 | John      | 2016 07 02 | Baker interview           | Boyfriend       | Interviewed   | Recording   | Interviewed |
|       2 | Liz       | 2016 07 02 | 0                         | Girlfriend      | Present       |             |             |
|       3 | Elliot    | 2016 06 01 | Brown, Brooks interview   | Individual      | Interviewed   | * Recording | Interviewed |
|       0 | Catherine | 2016 08 03 | Drake meeting             |                 | Present       | Recording   | Present     |
+---------+-----------+------------+---------------------------+-----------------+---------------+-------------+-------------+

显然,这更简洁、更紧凑。数据行数已从 6 table 中的 36 条减少到 1 条中的 11 行。数据元素(non-null 个单元格)数量的减少并不显着,从 100 个减少到 85 个。相关数据非常接近,可以更轻松地避免错误或查看任何存在的错误。

在此 table 中,使用零代替空值,以便允许前四个字段形成主键,确保这四个字段之间的唯一性。在字段名称中,例如"CP_Role",表示"Case-person role",即此人在案例中的角色。

冗余减少了,但没有消除。与其他冗余的十三个数据元素在此示例中用星号标记。这种冗余是对 data-entry 错误的有害邀请。但是,在 table.

中自动检查此类错误相当简单

现阶段实现此 four-way 关系 table 的最大问题是将数据从六个二进制 table 折叠到其中。创建一个包含所有必需字段的 table 很容易,然后将六个 table 的所有行附加到其中,对于缺少的键,值为零。这使得 5,902 条记录的组合 table。如果上面示例场景中的数字可以外推到真实数据,那么记录的数量可以减少到大约 1,800 条,这意味着可以删除 4,000 多条记录!我目前正在研究组合中的模式d table,寻求自动合并和删除多余行组的方法。很slow-going。

比制作这个新 table 所花费的时间更糟糕的是,我不完全相信结果将是数据的最佳表示。

问题

我是否遗漏了这种方法中的重要内容?有没有更智能的方法来管理这些 collection 数据?数据库理论是否提供了一种更好的方式来表示这些关系?

您可以在任何数据库书籍中找到如何构建数据库。例如我想出了:

接下来我们需要一些数据输入表单。数据输入表格旨在获取案例数据并将其分类到适当的数据库表中。所以数据输入者不需要知道数据库的结构,只需要输入实际的数据。很难找到有关为一对多和多对多表格制作数据输入表格的信息。这是一个 link:

create form to add records in multiple tables

这是我为此数据制作的数据输入表单和最终子表单:

1 对 m 关系的第 1 侧是表单,第 m 侧是子表单。在这里,我将使用向导创建的 file/persons 表单拖到同样使用向导创建的文件表单上。为了能够表示第二个 1 到 m 关系,我们将表单上保存外键的文本框替换为组合框。这里 ID_Person 已被组合框替换,因此数据输入者不必知道任何有关 ID_person 的信息,而只需选择人员姓名即可。 结果是数据输入者不需要了解数据库中的关键关系,只需输入案例数据即可。