如何规范化可以链接到一个或多个表的表?

时间:2018-03-03 01:33:05

标签: sql database database-design relational-database database-normalization

我想知道是否有人可以帮助我解决我面临的规范化问题,当我尝试创建一个单独的通信表时,我正在处理的个人项目。假设我有以下表格和表格列:

表A:

Table_A_Id,Date,Name,Agent_Id(FK),Notes

代理商表:

Agent_Id,日期,姓名,电话,电子邮件,便笺

直接联系表

D_C_Id,日期,姓名,电话,电子邮件,备注

以上是我的实际表格的示例,但描述了我的问题。

基本上为了将上面的表规范化为1NF,我需要将Notes列拆分为其单独的表,以帮助使表成为原子,并遵守1NF规则。我想将其拆分为一个名为通信表的单独列,这可以让我跟踪我何时进行与相应表格和我讨论过的内容的对话。

我不确定如何最好地处理拆分通讯表。因为表A中的Notes也链接到表中的代理,但代理表中的Notes列仅与代理进行的通信有关。

因此,您推荐以下哪一项最适合通信表:

示例1:

通讯表

Com_Id,Date,Link_Table,Link_Table_Id,Notes

  • 此处Link_Table应定义正在处理的特定表,Link_Table_Id是Link_Table上的特定ID

更新

抱歉,我忘记了,我还需要在上面添加另一个名为 Communicated_With 的列,因为可能存在与表A相关的通信可能与其他代理或人员发生的情况。

因此表格如下:

Com_Id,Date,Link_Table,Link_Table_Id,Communicated_With,Notes

OR

示例2:

通讯表

Com_Id,Date,Table_A_Id,Agent_Id,D_C_Id,Notes

  • 此处所有不相关的Id列必须设置为null,而相关的colum使用Id定义。

OR

示例3:

通讯表

Com_Id,Date,Notes

  • 此处所有其他表都有此表的外键。 (但是,这可能会迫使我重复其余的列只是为了识别它的不同列。)

更新2

考虑到一个新的解决方案,在查看了一些YouTube视频后,我注意到可能会有一个联接表。

示例4

通讯表(与示例1相同,没有“Comminicated_With”列) Com_Id,Date,Link_Table,Link_Table_Id,Communicated_With,Notes

COMM_AGENT_JOIN表 com_Id,Agent_Id

  • 我觉得这可能有用,因为它允许我使用Link_Table和Link_Table_Id来匹配正在表示的表,然后最后COMM_AGENT_JOIN_Id可用于指定与Link_Table链接的时间与哪个代理进行通信表-A。

很抱歉,如果答案是直截了当的,我上次在2年前做过规范化,因此一直在努力做到这一点。

谢谢。

1 个答案:

答案 0 :(得分:1)

这不是关于如何将表格放入1NF的答案。但我希望它会有所帮助。

在创建数据库时,我们通常不会想到1NF,2NF等。我们考虑要建模什么以及有哪些实体。当我们想到这一点时,数据库通常已经在5NF左右。如果有疑问,我们可以使用NF作为一种清单。

我不知道你的确切要求,所以这里有很多猜测或只是一般建议。也许你的一个问题是你正在使用名词" notes"它并没有准确描述这是什么。之后你称之为"往来",但都是"注意" ="对应"?

您的数据库是关于您直接从代理商或服务公司获得的服务。所以我看到的一个实体就是这个提供者:

<强>提供商

  • PROVIDER_ID
  • 名称
  • contact_person_name
  • 电话
  • 电子邮件
  • 类型(代理或最终服务提供商)

如果提供商可以拥有多个联系人,电话和电子邮件,那么您可以将其设为provider_contact表:

<强>提供商

  • PROVIDER_ID
  • 名称
  • 类型(代理或最终服务提供商)

<强> provider_contact

  • provider_contact_id
  • 名称
  • 电话
  • 电子邮件
  • PROVIDER_ID

至于注释:如果有提供者的注释(&#34;总是要求Jane;她是那里最专业的。&#34;)或联系(&#34; Jane已经工作了)在伦敦和马德里。&#34;),我通常会将这个只是一个文本列,您可以输入任何您喜欢的内容。您甚至可以存储HTML或Word文档。我想,每个提供商不需要多个文档。

现在也有服务。您需要提供哪个服务列表,然后添加这些表:service(存在哪些服务)和provider_service(谁提供哪些服务)。但也许你可以不用它,因为你知道存在哪些服务以及谁提供它们并且不想在你的模型中使用它。

我不知道您是想要输入服务查询还是只是已经修复过的服务合同。在任何情况下,您可能希望service_contract表具有状态或不具有状态。

<强> service_contract

  • service_contract_id
  • provider_id(或者可能是provider_contact_id?)
  • 服务(自由文本或引用服务表的service_id)
  • VALID_FROM
  • 失效日期

在这里,您可能会有类似的注释,我们仍在等待文件。简说,他们将在2018年3月到来。&#34;,这也只是一栏。

然后你说你想要通信,这可能是一个额外的表service_contract_correspondance

<强> service_contract_correspondance

  • service_contract_correspondance_id
  • service_contract_id
  • 类型(从提供商处收到或发送给提供商)
  • 文本

但话说回来,也许你可以没有它。您是否需要访问单个通讯(例如&#34;给我2017年12月和#34的所有通信;或&#34;删除超过一年的所有通信&#34;)?或者单一合同上会有数以千计的通信吗? Mabe没有。也许你可以再次将其视为单个文档(文本,HTML,Word,...),并将其添加为表格中的一个字段。

包含多个联系人的文字,例如

January 2, 2018 Jane
She says they'll need to weeks to make an offer.

January 20, 2018 
I asked about the status. Talked with some Thomas Smith. He says they'll call us tomorrow.

January 21, 2018 Jane
She has emailed the contract for us to sign.

本身并不反对NF1。只要您对数据库中的详细信息不感兴趣(例如,您永远不会在合同中单独选择所有1月份的通信),那么对于数据库来说这是原子的;无需改变这一点。

与联系人相同。如果你的字符串专栏只有&#34; Jane(销售人员)123-45678 jane@them.com,Jack(助手)123-98765 jack@them.com" ;,这本身并不是针对NF1 。只要您不想仅选择姓名或查看电话号码,但始终将字符串视为 联系人,那么就这样做。

您知道,这一切都归结为您想要建模的内容以及您希望如何使用数据。是的,有代理商和直接提供商,但两者之间的区别是否需要两个不同的表?是的,每个合同都有一份通信年表,但是你真的需要将它们分成数据库中的单个对应物吗?