代码之家  ›  专栏  ›  技术社区  ›  WW.

这是在关系数据库中建模地址信息的好方法吗?

  •  26
  • WW.  · 技术社区  · 16 年前

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

    选择1

    创建一个单独的地址表。从供应商表和采购订单表到地址表都有一个外键。仅允许在地址表上插入和删除,因为更新可能会超出您的预期。然后,我将有一些预定任务,从地址表中删除不再被任何对象引用的任何行,这样就不会留下未使用的行。也许在地址表中的所有非pk列上也有一个唯一的约束来阻止重复。

    过一会儿,我将根据旧订单的日期整体删除它们。正是在这之后,我打算对任何不再被任何东西引用的地址记录进行垃圾收集(否则感觉就像是在制造泄漏)。

    7 回复  |  直到 16 年前
        1
  •  27
  •   Eric Z Beard    16 年前

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

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

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

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

    这样,您的地址完全不知道它们是如何被使用的,并且您的实体(用户、帐户)也不直接知道关于地址的任何信息。这完全取决于您创建的链接表(在本例中是useraddress,但您可以根据您的模型做任何事情)。

        2
  •  6
  •   Paul Sonier    16 年前

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

    而且我强烈建议保留旧的地址数据;不要运行进程来清理它。除非您的数据库非常繁忙,否则您的数据库软件将能够处理多余的数据。真正地我看到的关于数据库的一个常见错误是试图过度优化;您确实想优化查询,但不想优化未使用的数据。(同样,如果您的数据库活动非常频繁,您可能需要做一些事情,但几乎可以肯定的是,您的数据库在表中仍然有多余数据的情况下工作得很好。)在大多数情况下,简单地让数据库增长实际上比试图优化它更有利。(从表中删除零星数据不会导致数据库大小的显著减小,如果这样做了,那么重新编制索引可能会对数据库造成巨大的消耗。)

        3
  •  2
  •   Stein G. Strindhaug    16 年前

    我想我同意约翰逊的观点。。

    关于(蜗牛)邮件地址的另一件事是,由于您希望包括国家/地区,我假设您希望在国际范围内发送/发送邮件,请保持地址字段主要为自由格式文本。当挪威没有邮政编码,我们有4位数的邮政编码时,要编一个5位数的邮政编码真的很烦人。

    最好的领域是:

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

        4
  •  1
  •   JohnFx    16 年前

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

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

        5
  •  1
  •   cagcowboy    16 年前

    为什么地址表上的任何一行都没有使用?使用它们的采购订单肯定还会指出它们?

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

        6
  •  0
  •   HLGEM    16 年前

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

    地址表是个好主意。对其进行唯一约束,以便同一实体不能有重复的地址。你可能仍然会得到它们,因为用户可能会添加另一个,而不是查找它们,如果它们的拼写稍有不同(St.而不是Street),唯一的约束不会阻止这一点。将创建订单时的数据复制到订单。这是一种需要多条记录的情况,因为您需要发送到何处的内容的历史记录。仅允许对表进行插入和删除对我来说没有任何意义,因为它们并不比更新更安全,并且需要对数据库进行更多的工作。在对数据库的一次调用中完成更新。如果您的想法中有地址更改,则必须先删除旧地址,然后插入新地址。不仅对数据库进行了更多的调用,而且发生代码错误的几率增加了一倍。

        7
  •  0
  •   Stephan Eggermont    16 年前

    我看到每个使用选项1的系统都会遇到数据质量问题。5年后,30%的地址不再是当前地址。