我想知道这是不是一个好的设计。我有许多需要地址信息的表格(例如街道,邮政编码/邮编,国家,传真,电子邮件)。有时相同的地址将重复多次。例如,可以针对供应商存储地址,然后针对发送给他们的每个采购订单存储地址。然后,供应商可以更改其地址,并且任何后续采购订单都应具有新地址。它比这更复杂,但这是一个示例要求。
选项1 将所有地址列作为属性放在各个表上。在创建时将详细信息从供应商复制到PO。可能存储
的多个副本选项2 创建一个单独的地址表。从供应商和采购订单表到地址表有一个外键。只允许在地址表上插入和删除,因为更新可能会比您想要的更改。然后我会有一些计划任务,删除地址表中不再被任何东西引用的任何行,因此未留下未使用的行。也许对地址表中的所有非pk列也有一个唯一的约束来阻止重复。
我倾向于选择2.有更好的方法吗?
编辑:我必须保留采购订单上的地址,就像发送时一样。此外,我建议它有点复杂,因为可能有一个传递地址和一个帐单地址(还有一堆其他表有地址信息)。
过了一会儿,我会根据日期删除旧的采购订单。在此之后,我打算垃圾收集任何地址记录,这些记录不再被任何东西引用(否则感觉就像是在创建泄漏)。
答案 0 :(得分:26)
我实际上将此作为我的面试问题之一。以下是一个好的开始:
Addresses
---------
AddressId (PK)
Street1
... (etc)
和
AddressTypes
------------
AddressTypeId
AddressTypeName
和
UserAddresses (substitute "Company", "Account", whatever for Users)
-------------
UserId
AddressTypeId
AddressId
这样,您的地址完全不知道它们的使用方式,您的实体(用户,帐户)也不直接了解地址。这完全取决于您创建的链接表(在这种情况下是UserAddresses,但您可以根据您的模型做任何事情)。
对于潜在大型数据库的一个有点矛盾的建议:继续将“主要”地址直接放在您的实体上(在本例中为Users表中)以及“HasMoreAddresses”字段。与仅使用上面的干净设计相比,它看起来很蹩脚,但可以简化典型用例的编码,而非规范化可以对性能产生很大的影响。
答案 1 :(得分:6)
选项2,毫无疑问。
需要牢记的一些重要事项:设计的一个重要方面是向用户指示地址何时相互关联。即公司地址与送货地址相同;如果他们想要更改送货地址,他们是否也想更改公司地址,或者他们是否想要指定新的装货码头?这种东西,以及向用户呈现这些信息并以这种粒度改变事物的能力非常重要。关于更新,这也很重要;为用户提供“拆分”条目的粒度。并不是说这种UI很容易设计;事实上,这是一个婊子。但这非常重要;任何不足都会让你的用户非常沮丧和烦恼。
也;我强烈建议保留旧的地址数据;不要运行一个进程来清理它。除非您拥有非常繁忙的数据库,否则您的数据库软件将能够处理多余的数据。真。我看到的关于数据库的一个常见错误是试图过度优化;你想要优化你的查询,但你不想优化你的未使用的数据。 (同样,如果您的数据库活动非常高,您可能需要做一些事情,但几乎可以肯定的是,您的数据库在表格中仍然存在过多数据时仍能正常工作。)在大多数情况下,它实际上更有利简单地让你的数据库增长,而不是尝试优化它。 (从表中删除偶发数据不会导致数据库大小的显着减少,并且当它发生时......好吧,重新编制索引会导致数据库的巨大消耗。)
答案 2 :(得分:3)
我认为我同意JohnFx ..
关于(snail-)邮件地址的另一件事,因为你想要包括国家我认为你想在国际上发货/邮寄,请保持地址字段大多是自由形式的文本。当挪威没有邮政编码时,必须编制一个5位数的邮政编码真的很烦人,我们有4位数的邮政编码。
最好的字段是:
如果美国邮政系统要求使用特定格式的邮政编码,那么这应该是全球性的,然后包含它也可以选择,除非选择美国作为国家/地区。每个人都知道如何格式化他们国家的地址,所以只要你保留换行符就可以了......
答案 3 :(得分:1)
您是否想保留最初在采购订单上的地址的历史记录?
如果是,请使用选项1,否则将其存储在供应商表中,并将每个采购订单链接到供应商。
BTW:数据库设计不佳的一个明确迹象是需要一个自动化作业来保持数据“清理”或同步。选项2可能是一个坏主意答案 4 :(得分:1)
为什么地址表中的任何行都不会被使用?当然,使用它们的采购订单仍会指出它们吗?
在我看来,停止重复应该是优先事项,因此无需进行任何清理。
答案 5 :(得分:0)
对于订单,如果订单已发送,则人员(或公司)地址发生变化时,您永远不会想要更新地址。如果订单有问题,您需要记录订单实际发送的位置。
地址表是个好主意。对其进行唯一约束,以便同一实体不能具有重复的地址。您仍然可以获得它们,因为用户可能会添加另一个而不是查找它们,如果它们拼写的内容略有不同(St.而不是Street),则唯一约束不会阻止它。将订单创建时的数据复制到订单。这是您需要多个记录的一种情况,因为您需要记录您在哪里发送的内容。只允许对表进行插入和删除对我没有意义,因为它们不比更新更安全,并且涉及更多数据库工作。在对数据库的一次调用中完成更新。如果您的想法中的地址发生了变化,那么您必须首先删除旧地址,然后插入新地址。不仅需要更多调用数据库,而且还有两倍的代码错误。
答案 6 :(得分:0)
我看到使用选项1的每个系统都会遇到数据质量问题。 5年后,30%的地址将不再是最新的。