【问题标题】:How to best represent addresses in a database [duplicate]如何最好地表示数据库中的地址[重复]
【发布时间】:2010-11-29 13:11:09
【问题描述】:

可能的重复:
Is there common street addresses database design for all addresses of the world?
What is the “best” way to store international addresses in a database?
Best practices for consistent and comprehensive address storage in a database

我目前有四个表,客户、联系人、设施和客户。

每个表都有以下字段: AddressLine1, AddressLine2, City, StateOrProvince, PostalCode。

我想将地址移到单独的表格中,并且还可以指定地址类型(帐单、送货、主要等)。

我的解决方法如下:

  1. 从客户、联系人、设施和客户中删除 AddressLine1、AddressLine2、City、StateOrProvince、PostalCode。
  2. 使用 AddressID(PK)、AddressLine1、AddressLine2、City、StateOrProvince、PostalCode、LastUpdateUser、LastUpdateTime 字段创建 Addresses 表。
  3. 创建包含 AddressTypeID、AddressTypeName、AddressTypeDescription、AddressTypeActive、LastUpdateUser、LastUpdateTime 字段的 AddressTypes 表
  4. 创建包含字段 CustomerID、AddressID、AddressTypeID、CustomerAddressActive、LastUpdateUser、LastUpdateTime 的 CustomerAddresses 表
  5. 创建包含字段 ClientID、AddressID、AddressTypeID、ClientAddressActive、LastUpdateUser、LastUpdateTime 的 ClientAddresses 表
  6. 创建包含字段 ContactID、AddressID、AddressTypeID、ContactAddressActive、LastUpdateUser、LastUpdateTime 的 ContactAddresses 表
  7. 创建包含字段 FacilityID、AddressID、AddressTypeID、FacilityAddressActive、LastUpdateUser、LastUpdateTime 的 FacilityAddresses 表

我正在寻找指导以确定是否有比我设计的解决方案更好的解决方案。为什么大家都这么想?

编辑:此时我不关心美国以外的任何事情,也不关心如何存储街道地址,即街道编号与整个街道地址。我是从数据库设计和表结构的角度来考虑的。

【问题讨论】:

标签: database-design data-modeling


【解决方案1】:

我曾经工作过的一位 DBA 告诉我这个 gem,它对我们非常有用(前两个步骤与您的解决方案相同):

  1. 从客户、联系人、设施和客户中删除 AddressLine1、AddressLine2、City、StateOrProvince、PostalCode。
  2. 创建包含 AddressTypeID、AddressTypeName、AddressTypeDescription、AddressTypeActive、LastUpdateUser、LastUpdateTime 字段的 AddressTypes 表
  3. 创建包含字段 AddressID(PK)、AddressTypeID(FK)、AddressLine1、AddressLine2、City、StateOrProvince、PostalCode、LastUpdateUser、LastUpdateTime、CustomerID(FK)、ClientID(FK)、ContactID(FK)、FacilityID(FK) 的 Addresses 表)
  4. 在地址表上,设置一个约束,以便一次只能有一个 CustomerID、ClientID、ContactID 或 FacilityID 外键为非 NULL。

这样您就可以将所有地址放在一个表中,它们可以引用您需要的任何记录,您的引用完整性是完整的,并且您没有必须遍历的中间表。

缺点是,如果您想将地址添加到新的对象类(例如 Employee 表),您必须在 Addresses 表中添加一个 EmployeeID 列,但这很容易。

【讨论】:

  • 添加这么多主键有什么意义,反过来可以使生活更轻松,并允许客户(只是一个示例)可以拥有多个地址的关系。
  • 客户可以拥有多个地址。 Addresses 表可以有多个引用相同 CustomerID 的行。您不能让相同的地址同时引用客户和联系人。
  • 如果一个地址引用了两个不同的客户,因为他们住在同一所房子里怎么办?
  • @nonsensecreativity,你可以有两个地址具有相同的 AddressLine1, City, StateOProvince, PostalCode
【解决方案2】:

我们的数据库中您可能需要考虑的另一件事是在地址表上设置一个对应标志,并使用触发器强制每个人只能将一个地址作为对应关系。我们向我们数据库中的人发送大量邮件,并且知道该人的三个地址中的哪一个是我们在发送邮件非常宝贵时需要使用的地址。这也使得查询时更容易每人只获取一个地址,以避免在某些报告中获得每人多条记录。

【讨论】:

    【解决方案3】:

    我会考虑一个带有

    的 AddressLink(名称?)表
    LinkTypeID (Customer,Client,Contact,Facility) -- needs additional TypeID table
    ID (CustomerID,ClientID...)
    AddressID
    AddressTypeID
    AddressActive
    LastUpdateUser
    LastUpdateTime
    

    添加一个新的地址链接类型意味着添加一个新的 LinkTypeID 没有新的 [TypeID]Addresses 表,不需要修改查询,如果您正在寻找地址的所有用途(用于删除等),那么只有一个地方看。

    无论如何,这与我们的做法非常相似。

    哦,我们的 Addresses(等效)表中有一个 AddressLine3 用于一些奇怪的异常情况。

    【讨论】:

    • 如何对具有这种结构的 ID 实施外键约束?还是你不打扰?
    • 插入/修改触发器验证 ID 列相对于 LinkTypeID 是否有效。 LinkTypeID、AddressID 和 AddressTypeID 列上的 FK,以及父表上的“删除限制”。我认为这是以声明方式完成的,但也可能是触发器。 (MS SQL Server 2005)
    【解决方案4】:

    我还想再添加一件事,为了简单起见,创建将地址信息扩展到您的表的视图,否则您可能会讨厌自己以这种方式设计数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2015-10-23
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多