27

我想知道这是否是一个好的设计。我有许多需要地址信息的表格(例如街道、邮政编码/邮编、国家、传真、电子邮件)。有时同一个地址会重复多次。例如,可以针对供应商存储地址,然后在发送给他们的每个采购订单上存储地址。然后供应商可以更改他们的地址,任何后续的采购订单都应该有新的地址。它比这更复杂,但这是一个示例要求。

选项 1 将所有地址列作为属性放在各个表上。在创建 PO 时将详细信息从供应商复制到 PO。可能存储多个副本

选项 2 创建单独的地址表。有一个从供应商和采购订单表到地址表的外键。只允许在地址表上插入和删除,因为更新可能会超出您的预期。然后我会有一些计划任务,从地址表中删除任何不再被任何东西引用的行,因此不会留下未使用的行。也许对地址表中的所有非 pk 列也有一个唯一约束,以停止重复。

我倾向于选项2。有更好的方法吗?

编辑:我必须保持采购订单上的地址与发送时的地址相同。另外,我建议的情况要复杂一些,因为可能有送货地址和帐单地址(还有一堆其他包含地址信息的表)。

一段时间后,我将根据日期批量删除旧的采购订单。正是在这之后,我打算对任何不再被任何东西引用的地址记录进行垃圾收集(否则感觉就像我正在创建泄漏)。

4

7 回答 7

28

实际上,我将此作为我的面试问题之一。以下是一个很好的起点:

Addresses
---------
AddressId (PK)
Street1
... (etc)

AddressTypes
------------
AddressTypeId
AddressTypeName

UserAddresses (substitute "Company", "Account", whatever for Users)
-------------
UserId
AddressTypeId
AddressId

这样,您的地址完全不知道它们是如何被使用的,并且您的实体(用户、帐户)也不直接了解地址的任何信息。这完全取决于您创建的链接表(在这种情况下为 UserAddresses,但您可以做任何适合您的模型的事情)。

对于一个潜在的大型数据库,有一条有点矛盾的建议:继续在您的实体上直接放置一个“主”地址(在本例中为 Users 表中)以及一个“HasMoreAddresses”字段。与仅使用上面的简洁设计相比,这似乎很棘手,但可以简化典型用例的编码,并且非规范化可以对性能产生很大影响。

于 2008-11-20T22:28:21.080 回答
7

选项2,毫无疑问。

一些重要的事情要记住:当地址相互链接时向用户指示是设计的一个重要方面。即公司地址与送货地址相同;如果他们想更改送货地址,他们是否也想更改公司地址,还是他们想指定一个新的装卸码头?这种东西,以及向用户呈现这些信息并以这种粒度改变事物的能力是非常重要的。这对于更新也很重要;为用户提供“拆分”条目的粒度。并不是说这种 UI 很容易设计;事实上,这是一个婊子。但这真的很重要;几乎肯定会导致您的用户非常沮丧和恼火。

还; 我强烈建议保留旧地址数据;不要运行一个进程来清理它。除非您有一个非常繁忙的数据库,否则您的数据库软件将能够处理多余的数据。真的。我看到的关于数据库的一个常见错误是试图过度优化。你确实想优化你的查询,但你不想优化你未使用的数据。(同样,如果您的数据库活动非常高,您可能需要一些东西来执行此操作,但几乎可以肯定的是,您的数据库在表中仍有多余数据的情况下可以正常工作。)在大多数情况下,它实际上更有利简单地让您的数据库增长而不是尝试优化它。(从表中删除零星数据不会导致数据库大小显着减少,

于 2008-11-20T22:28:57.180 回答
2

您想保留采购订单上最初的地址的历史记录吗?

如果是,则使用选项 1,否则将其存储在供应商表中并将每个采购订单链接到供应商。

顺便说一句:糟糕的数据库设计的一个明确迹象是需要自动化作业来保持数据“清理”或同步。以这种方式衡量,选项 2 可能是个坏主意

于 2008-11-20T22:11:57.057 回答
2

我想我同意JohnFx ..

关于(蜗牛)邮件地址的另一件事,因为你想包括国家,我假设你想在国际上运送/邮寄,请保留地址字段主要是自由格式的文本。当挪威没有邮政编码时,必须编一个 5 位数的邮政编码真的很烦人,我们有 4 位数的邮政编码。

最好的领域是:

  • 名称/公司
  • 地址(多行文本区域)
  • 国家

这应该是相当全球化的,如果美国邮政系统需要特定格式的邮政编码,那么也包括它,但除非选择美国作为国家,否则它是可选的。每个人都知道如何在他们的国家格式化地址,所以只要你保留换行符就可以了......

于 2008-11-20T22:28:22.203 回答
1

为什么地址表上的任何行都会变为未使用?使用它们的采购订单肯定还会指向它们吗?

在我看来,停止重复应该是优先事项,因此不需要进行任何清理。

于 2008-11-20T22:27:48.943 回答
0

在订单的情况下,如果订单已发送,您将永远不想更新地址,因为个人(或公司)地址已更改。如果订单有问题,您需要记录实际发送订单的位置。

地址表是个好主意。对其进行唯一约束,使同一实体不能有重复的地址。您可能仍然会得到它们,因为用户可能会添加另一个而不是查找它们,并且如果它们拼写稍有不同(St. 而不是 Street),则唯一约束不会阻止这种情况。将创建订单时的数据复制到订单中。这是您需要多个记录的一种情况,因为您需要历史记录来记录您发送的内容。只允许对表进行插入和删除对我来说毫无意义,因为它们并不比更新更安全,并且涉及到数据库的更多工作。一次调用数据库即可完成更新。如果您的想法中的地址发生变化,那么您必须先删除旧地址,然后插入新地址。

于 2008-11-20T22:29:02.920 回答
0

我已经看到每个使用选项 1 的系统都陷入数据质量问题。5 年后,所有地址的 30% 将不再是最新的。

于 2009-02-03T18:24:14.983 回答