是否有任何最佳实践(甚至是标准)在数据库中以一致和全面的方式存储地址?
更具体地说,我相信在这个阶段,地址存储有两种情况:
国家特定的设计/解决方案将是一个很好的开始。
ANSWER :这个问题似乎还没有完美答案,但是:
答案 0 :(得分:30)
我自己也在考虑这个问题。到目前为止,这是我的松散想法,我想知道其他人的想法。
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
类型,其中包含每种类型地址的子类,例如AmericanAddress
,CanadianAddress
,GermanAddress
等等?这些地址类型中的每一种都知道如何格式化自己,并且可选地会对字段的验证有所了解。
他们还可以返回关于每个字段的某种类型的元数据,例如以下伪代码数据结构:
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语句。
你可以想象这个过程是这样的:
address.GetMetadata()
或类似方法,并接收如上所述的AddressFieldMetadata
结构列表。它可以使用此元数据来确定要显示的字段(忽略is-applicable
设置为false
的字段),标记这些字段的内容(使用field-name
成员),在特定订单,并对该数据执行粗略的表示级验证(使用is-required
,validation-regex
和allowed-values
成员。)address.SetField()
(对应于上面的枚举)及其给定值调用field-number
方法。然后,Address
对象或其策略可以对这些字段执行某些高级地址验证,调用地址清除程序等。如果我们想让Address
对象本身在创建后表现得像一个不可变对象,那么上面可能会略有不同。 (我可能会尝试这样做,因为Address
对象实际上更像是一个数据结构,并且可能永远不会有任何与自身相关的真实行为。)
这有什么意义吗?我是否偏离了OOP路径太远了?对我来说,这代表了一种非常明智的折衷方案,即如此抽象,实现几乎不可能(xAL)与严格偏向美国。
2年后更新:我最终得到了一个类似于此的系统,并在my defunct blog处写了这篇文章。
我觉得这个解决方案是遗留数据和关系数据存储之间的正确平衡,至少对于电子商务世界而言。
答案 1 :(得分:3)
我建议您使用Address
表格,并将其基于xAL跟踪的数据。
答案 2 :(得分:1)
在英国有一种名为PAF from Royal Mail
的产品这为每个地址提供了一个唯一的密钥 - 尽管如此,仍然需要跳过。
答案 3 :(得分:1)
如果你想要一致性,我基本上会看到两个选择:
广告1.我使用SAS系统,SAS Institute提供数据清理工具 - 这基本上对您的数据进行了一些检查和验证,并建议合并“Abram Lincoln Road”和“Abraham Lincoln Road”走进同一条街。我还认为它借鉴了包含城市邮政代码匹配等的国家数据库。
广告2.您构建了一个多选列表(即基本数据),添加新条目的人员从基本数据中的现有条目中进行选择。在事实表中,您将键存储到街道名称而不是街道名称本身。如果您检测到拼写错误,则只需在基本数据中进行更正,并通过关键关系对所有实例进行更正。
请注意,这些选项不会相互排除,您可以同时使用这两种方法。
答案 4 :(得分:1)
关于如何构建地址的权威通常是邮政服务,所以首先我会检查邮政服务为您经营的主要市场使用的数据元素。
有关国际邮政地址格式的详细信息,请参见万国邮政联盟网站:http://www.upu.int/post_code/en/postal_addressing_systems_member_countries.shtml
答案 5 :(得分:1)
“xAl是最接近弹出的全球标准的东西。虽然看起来有点矫枉过正,但我不确定很多人会想要在他们的数据库中实现它......”
这不是一个相关的论点。如果系统需要“全面和一致”(即全世界),那么实现地址并不是一项简单的任务。实施这样的标准确实很耗时,但要满足规定的要求,仍然是强制性的。
答案 6 :(得分:0)
规范化您的数据库架构,您将拥有完美的一致性结构。这就是为什么: http://weblogs.sqlteam.com/mladenp/archive/2008/09/17/Normalization-for-databases-is-like-Dependency-Injection-for-code.aspx
答案 7 :(得分:0)
我之前问了一些非常类似的事: Dynamic contact information data/design pattern: Is this in any way feasible?。
简短回答:在数据库中存储adderres或任何类型的联系信息都很复杂。上面的可扩展地址语言(xAL)链接有一些有趣的信息,这些信息最接近我所遇到的标准/最佳实践......
答案 8 :(得分:0)
在美国,我建议选择一个国家地址变更供应商,并在他们返回后对数据库进行建模。