26

是否有任何最佳实践(甚至标准)可以在数据库中以一致和全面的方式存储地址?

具体来说,我认为现阶段地址存储有两种情况:

  • 您只需要将地址与人、建筑物或任何物品相关联(最常见的情况)。那么一个带有文本列(address1、address2、zip、city)的平面表可能就足够了。这不是我感兴趣的情况。
  • 您想对您的地址进行统计:特定街道、城市或...中有多少物品然后您想避免任何类型的拼写错误,并确保一致性。我的问题是关于这种特定情况下的最佳实践:建模一致地址数据库的最佳方法是什么?

一个国家特定的设计/解决方案将是一个很好的开始。

回答:这个问题似乎还没有完美的答案,但是:

  • 正如 Hank所建议的, xAL是最接近出现的全球标准的东西。不过,这似乎有点矫枉过正,我不确定很多人会想在他们的数据库中实现它......
  • 要开始自己的设计(针对特定国家/地区),Dave万国邮政联盟(UPU) 网站的链接是一个很好的起点。
  • 至于法国,地址有一个规范(非官方,但事实上的标准),上面有AFNOR XP Z10-011(仅限法语)这个可爱的名字,并且必须付费。万国邮联对法国的描述基于此规范。
  • 我碰巧找到了瑞典的等效规范:SS 613401
  • 在欧洲层面,已经做出了一些努力,形成了标准 EN 14142-1。它可通过CEN 国家成员获得。
4

9 回答 9

32

我自己也一直在思考这个问题。到目前为止,这是我的松散想法,我想知道其他人的想法。

谷歌和雅虎的地理编码服务都使用 xAL(及其包含个人姓名的姐妹 XNAL),这给了它一定的权重。但是由于可以在 xAL 中以许多不同的方式描述相同的地址——有些方式比其他方式更具体——所以我看不出 xAL 本身是如何成为数据存储的可接受格式。但是,可以使用其中的一些字段名称,但实际上,在我公司运送到的 16 个国家/地区中,唯一可以使用的基本格式如下:


enum address-fields 
{
    name,
    company-name,
    street-lines[], // up to 4 free-type street lines
    county/sublocality,
    city/town/district,
    state/province/region/territory,
    postal-code,
    country
}

这很容易映射到单个数据库表中,只允许在大多数列上使用 NULL。这似乎是亚马逊和许多组织实际存储地址数据的方式。所以剩下的问题是我应该如何在程序员和任何 GUI 代码都可以轻松使用的对象模型中对此进行建模。我们是否有一个基Address类型以及每种地址类型的子类,例如AmericanAddressCanadianAddressGermanAddress等等?这些地址类型中的每一个都知道如何格式化自己,并且可以选择了解一些关于字段验证的信息。

它们还可以返回有关每个字段的某种类型的元数据,例如以下伪代码数据结构:


structure address-field-metadata 
{
    field-number,     // corresponds to the enumeration above
    field-index,      // the order in which the field is usually displayed
    field-name,       // a "localized" name; US == "State", CA == "Province", etc
    is-applicable,    // whether or not the field is even looked at / valid
    is-required,      // whether or not the field is required
    validation-regex, // an optional regex to apply against the field
    allowed-values[]  // an optional array of specific values the field can be set to
}

事实上,我们可以采用稍微不那么面向对象的方法,让Address对象避开 .NET 属性并使用AddressStrategy来确定格式和验证规则,而不是为每个国家/地区创建单独的地址对象:


object address
{
    set-field(field-number, field-value),
    address-strategy
}

object address-strategy
{
    validate-field(field-number, field-value),
    cleanse-address(address),
    format-address(address, formatting-options)
}

设置字段时,该Address对象将在其内部AddressStrategy对象上调用适当的方法。

使用SetField()方法方法而不是使用 getter 和 setter 的属性的原因是,代码更容易以通用方式实际设置这些字段,而无需诉诸反射或 switch 语句。

你可以想象这个过程是这样的:

  1. GUI 代码调用工厂方法或类似方法来创建基于国家/地区的地址。(因此,国家下拉菜单是客户选择的第一件事,或者根据文化信息或 IP 地址为他们预先选择了一个很好的猜测。)
  2. GUI 调用address.GetMetadata()或类似方法并接收AddressFieldMetadata如上所述的结构列表。它可以使用此元数据来确定要显示的字段(忽略那些is-applicable设置为false的字段),标记这些字段的内容(使用field-name成员),以特定顺序显示这些字段,并对该数据执行粗略的演示级别验证(使用is-requiredvalidation-regexallowed-values成员)。
  3. GUI使用(对应于上面的枚举)及其给定值调用该address.SetField()方法。field-number然后,Address对象或其策略可以对这些字段执行一些高级地址验证,调用地址清理器等。

如果我们想让Address对象本身在创建后表现得像一个不可变对象,则上述内容可能会略有不同。(我可能会尝试这样做,因为Address对象实际上更像是一种数据结构,并且可能永远不会有任何与自身相关的真实行为。)

这有什么意义吗?我是否偏离 OOP 路径太远了?对我来说,这代表了在如此抽象以至于实现几乎不可能 (xAL) 与严格偏向美国之间的一种相当明智的折衷。


2 年后更新:我最终得到了一个与此类似的系统,并在我已停刊的博客上写了一篇关于它的文章。

我觉得这个解决方案是遗留数据和关系数据存储之间的正确平衡,至少对于电子商务世界来说是这样。

于 2009-01-05T22:54:29.870 回答
3

Address正如您所建议的,我将使用一个表格,并将其基于xAL跟踪的数据。

于 2008-09-24T09:34:34.510 回答
1

在英国,皇家邮政有一种名为 PAF的产品

这为每个地址提供了一个唯一的密钥——不过,有一些障碍可以跳过。

于 2008-09-24T09:34:59.190 回答
1

如果您想要一致性,我基本上会看到 2 个选择:

  1. 数据清理
  2. 基本数据表查找

广告 1. 我使用 SAS 系统,SAS Institute 提供了一个数据清理工具 - 这基本上会对您的数据进行一些检查和验证,并建议将“Abram Lincoln Road”和“Abraham Lincoln Road”合并到同一个街道。我还认为它利用了包含城市邮政编码匹配等的国家数据库。

广告2。您建立了一个多项选择列表(即基本数据),并且添加新条目的人从您的基本数据中的现有条目中进行选择。在您的事实表中,您存储街道名称的键而不是街道名称本身。如果您检测到拼写错误,您只需在基本数据中更正它,所有实例都会通过键关系更正。

请注意,这些选项并不相互排斥,您可以同时使用这两种方法。

于 2008-09-24T09:44:31.787 回答
1

在美国,我建议选择国家地址变更供应商,并根据他们返回的内容对数据库进行建模。

于 2008-09-24T10:57:44.200 回答
1

有关如何构建地址的权威通常是邮政服务,因此首先我将检查邮政服务在您经营的主要市场中使用的数据元素。

有关国际邮政地址格式的非常具体和详细的​​信息,请参见万国邮政联盟的网站:http ://www.upu.int/post_code/en/postal_addressing_systems_member_countries.shtml

于 2008-09-24T12:33:14.127 回答
1

“xAl 是最接近出现的全球标准的东西。不过,这似乎有点过头了,我不确定很多人会想在他们的数据库中实现它......”

这不是一个相关的论点。如果系统需要“全面和一致”(即全球范围内),则实施地址不是一项简单的任务。实施这样的标准确实很耗时,但要满足规定的要求仍然是强制性的。

于 2013-04-06T12:15:07.140 回答
0

标准化您的数据库模式,您将拥有正确一致性的完美结构。这就是为什么: http ://weblogs.sqlteam.com/mladenp/archive/2008/09/17/Normalization-for-databases-is-like-Dependency-Injection-for-code.aspx

于 2008-09-24T09:33:38.287 回答
0

我之前问过一些非常相似的问题:动态联系信息数据/设计模式:这是否可行?.

简短的回答:在数据库中存储地址或任何类型的联系信息很复杂。上面的可扩展地址语言 (xAL) 链接有一些有趣的信息,这些信息最接近我遇到的标准/最佳实践......

于 2008-09-24T10:17:24.220 回答