0

我正在从一个非常过时的系统创建/重建一个新系统,并且正在创建将在新系统中使用的模式。这些表需要一些认真的工作来进行规范化。

我使用的客户表中有很多重复的数据:

  • 一些客户是相关的,因为他们拥有相同的“母公司”。例如,像 Graybar Electric 这样的供应公司在美国有许多分支机构。在此客户表中,这些分支机构中的每一个都被列为单独的客户,例如“Graybar Electric - Seattle”。斯波坎分公司被列为“Graybar Electric - Spokane”。
  • 一个客户有一个帐单地址,但一个帐单地址可以是一个或多个客户。如果帐单地址与多个客户相关,则这些客户始终来自同一“母公司”
  • 但是,母公司的分支机构不一定共享相同的帐单地址。例如,“Stoneway Electric - 西雅图”的帐单地址可能与“Stoneway Electric-Everett”不同,但可能与“Stoneway Electric - Tacoma”共享帐单地址。
  • 并非所有客户都是分支机构,他们是他们自己的个人公司/客户,因此他们没有“母公司”。

这是我上面解释的快速视图:

Customer Name        |   Billing Address
--------------------------------------
CustomerA - Branch1  |  BillingAddress1
CustomerA - Branch2  |  BillingAddress1
CustomerA - Branch3  |  BillingAddress2
CustomerA - Branch4  |  BillingAddress3
CustomerB - Branch1  |  BillingAddress4
CustomerB - Branch2  |  BillingAddress4
CustomerC            |  BillingAddress5
CustomerD            |  BillingAddress6
etc....

所以,我想我想要表格:ParentCompanyCustomerBillingAddress。但我不确定的是如何关联这 3 个表。我看到的选择是:

  1. ParentCompany 到客户 (1:M),然后客户到帐单地址 (M:1)
  2. ParentCompany 到 BillingAddress (1:M),然后 BillingAddress 到客户 (1:M)

在做出我的选择时,我试图考虑哪个更容易在表单的用户界面中实现。我需要考虑:

  • 为现有母公司添加客户分支机构
  • 为尚不存在的母公司添加客户分支机构。
  • 添加不是母公司分支机构的客户。
  • 添加分公司客户时,用户将选择与母公司相关的现有帐单地址或输入新的帐单地址。
  • 现有的单一客户想要添加一个分支客户,因此现在新客户和原始单一客户都需要与新的母公司相关联。

所以我的问题是:

  1. 哪种模式最适合我的情况?
  2. 我需要考虑的上述每个选项是否有优点/缺点?
  3. 我还缺少其他选择或考虑吗?

感谢您的输入。

4

1 回答 1

0

所以,我想我想要表格:ParentCompanyCustomerBillingAddress。但我不确定的是如何关联这 3 个表。

你是在倒退。

你有客户。其中一些客户有母公司。

每家公司都有一个帐单地址。许多公司可能会共享一个帐单地址。

因此,让我们从客户和帐单地址开始。

Customer
--------
Customer ID
Customer Name
Billing Address ID
...

Billing Address
---------------
Billing Address ID
Billing Address Line 1
Billing Address Line 2
Billing Address City
Billing Address State
Billing Address Zip
... 

现在,当我们介绍一家母公司时会发生什么?我们不想改变客户和帐单地址之间的关系。由于并非每家公司都有母公司,因此我们将母公司设为 Customer 的子类。

Parent Company
--------------
Parent Company ID
Parent Company Name
...

Parent Company / Customer
-------------------------
Customer ID
Parent Company ID
Billing Address ID

关系表的关键是所有 3 个 ID 字段。如果您想通过母公司 ID 或账单地址 ID 获取关系,您可以使用其他唯一键。

所以让我们测试一下这个模式。

为现有母公司添加客户分支机构

在 Customer 表中添加一行,在 Parent Company/Customer 表中添加一行。母公司/客户表中的账单地址 ID 取代了客户表中的账单地址 ID。您的应用程序代码需要确保这一点。

为尚不存在的母公司添加客户分支机构。

在 Parent Company 表中添加一行。在 Customer 表中添加一行。在 Parent Company / Customer 表中添加一行。

添加不是母公司分支机构的客户。

在 Customer 表中添加一行。

添加分公司客户时,用户将选择与母公司相关的现有帐单地址或输入新的帐单地址。

这是一个与 GUI 相关的问题,但您从母公司/客户表中为母公司选择所有帐单地址,用户可以选择一个或键入新的帐单地址。您需要在(母公司 ID、帐单地址 ID、客户 ID)上的母公司/客户表上建立唯一索引,以使选择有效。

现有的单一客户想要添加一个分支客户,因此现在新客户和原始单一客户都需要与新的母公司相关联。

添加一个客户表行。添加 Parent Company 表行。将两行添加到 Parent Company / Customer 表以建立关联。如有必要,更新 Customer 表上的原始客户行。

祝您的数据库修订好运。

编辑以回答评论中的问题。

您能否详细解释一下母公司/客户表?此表是否将在 Customer 和 Parent Company 表之间建立关系?

此表关联母公司和客户。维基百科称它为联结表。它的存在是为了将母公司和客户联系在一起。

3张桌子之间的基数是多少?

每个母公司/客户关联的母公司/客户表上都会有一行。

另外,您能否详细说明一下您的声明:“关系表的键是所有 3 个 ID 字段。如果您想通过母公司 ID 或帐单地址 ID 获取关系,您可以使用其他唯一键。” 是还有其他要考虑的键吗?

我用key这个词来表示索引。抱歉,如果这让您感到困惑。

主要(集群)索引是(客户 ID、母公司 ID、账单地址 ID)。

您还需要在(母公司 ID、帐单地址 ID、客户 ID)上为您概述的 GUI 地址屏幕提供唯一索引。

根据您要查询的其他内容,您将需要额外的唯一索引。

您可以再定义 4 个唯一索引。可以从 3 个键列创建 6 个唯一索引。这称为笛卡尔积

当您在 Parent Company/Customer 表上运行非常慢的 SQL 选择时,您可以查看 where 子句。这通常表明您需要在表上建立一个新索引,而 where 子句会显示要在索引中放入哪些列。

最后,这是一个问题的答案。这不是教程。我无法牵着你的手指导你学习数据建模。我建议您研究有关数据库规范化的 Wikipedia 文章。

于 2013-06-24T13:07:51.607 回答