当前位置:  开发笔记 > 程序员 > 正文

在数据库中实现一致且全面的地址存储的最佳实践

如何解决《在数据库中实现一致且全面的地址存储的最佳实践》经验,为你挑选了1个好方法。

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

更具体地说,我认为在这个阶段有两种地址存储的情况:

您只需要将地址与人,建筑物或任何项目(最常见的情况)相关联.然后一个带有文本列(address1,address2,zip,city)的平面表就足够了.这不是我感兴趣的情况.

您想要对您的地址运行统计信息:特定街道或城市中的项目数量......然后您希望避免任何类型的拼写错误,并确保一致性.我的问题是关于这个特定情况下的最佳实践:建立一致地址数据库的最佳方法是什么?

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

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

正如汉克所建议的那样,xAL是最接近出现的全球标准的东西.虽然看起来有点矫枉过正,但我​​不确定很多人会想要在他们的数据库中实现它......

为了开始自己的设计(针对特定国家),Dave与万国邮政联盟(UPU)网站的链接是一个非常好的起点.

至于法国,地址有一个标准(非官方,但事实上的标准),其中有一个可爱的名字AFNOR XP Z10-011(仅限法语),并且必须付费.法国的UPU描述基于这一规范.

我碰巧找到了瑞典的等效标准:SS 613401.

在欧洲层面,已经做出了一些努力,产生了标准EN 14142-1.它可以通过CEN国家成员获得.

Nicholas Pia.. 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语句.

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

    GUI代码调用工厂方法或类似方法来创建基于国家/地区的地址.(那么,国家下拉菜单是客户选择的第一件事,或者根据文化信息或IP地址为他们预先选择好的猜测.)

    GUI调用address.GetMetadata()或类似方法,并接收AddressFieldMetadata如上所述的结构列表.它可以使用此元数据来确定要显示的字段(忽略is-applicable设置为的false字段),标记这些字段的内容(使用field-name成员),按特定顺序显示这些字段,以及对该数据执行粗略的表示级验证(使用is-required,validation-regexallowed-values成员).

    GUI address.SetField()使用field-number(对应于上面的枚举)及其给定值来调用方法.然后,Address对象或其策略可以对这些字段执行某些高级地址验证,调用地址清除程序等.

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

这有什么意义吗?我是否偏离了OOP路径太远了?对我来说,这代表了一种非常合理的妥协,它是如此抽象,以至于实现几乎不可能(xAL)与严格偏向于美国.


2年后更新:我最终得到了一个类似于此的系统,并在我已经不存在的博客上写了这篇文章.

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



1> Nicholas Pia..:

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

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语句.

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

    GUI代码调用工厂方法或类似方法来创建基于国家/地区的地址.(那么,国家下拉菜单是客户选择的第一件事,或者根据文化信息或IP地址为他们预先选择好的猜测.)

    GUI调用address.GetMetadata()或类似方法,并接收AddressFieldMetadata如上所述的结构列表.它可以使用此元数据来确定要显示的字段(忽略is-applicable设置为的false字段),标记这些字段的内容(使用field-name成员),按特定顺序显示这些字段,以及对该数据执行粗略的表示级验证(使用is-required,validation-regexallowed-values成员).

    GUI address.SetField()使用field-number(对应于上面的枚举)及其给定值来调用方法.然后,Address对象或其策略可以对这些字段执行某些高级地址验证,调用地址清除程序等.

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

这有什么意义吗?我是否偏离了OOP路径太远了?对我来说,这代表了一种非常合理的妥协,它是如此抽象,以至于实现几乎不可能(xAL)与严格偏向于美国.


2年后更新:我最终得到了一个类似于此的系统,并在我已经不存在的博客上写了这篇文章.

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

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有