web-dev-qa-db-ja.com

国際郵便/番地住所を保存するための認識されたフィールドのセットはありますか?

会場の住所を保存する必要があるイベントカレンダーサイトを設定しています。電子メール、IP、またはその他のアドレスではなく、番地/郵便番号。

私のサイトを国際的に機能させたいので、すべての可能な/合理的なアドレスをカバーするのに十分で正しいアドレスフィールドを持ちたいです。個々のフィールドにアクセスする必要がなかったため、以前はテキストブロックを使用していましたが、各アドレスから町/市を抽出できるようにしたいので、より具体的なフィールドとして保存するのが賢明です。

質問:国際郵便/番地を保存するための認識されたフィールドのセットはありますか?それとも国別ですか?

Schema.orgの PostalAddress 形式は、1つの例を示す場合があります。

2
MichaelJones

これ StackOverflowで質問および回答されましたNicholas Piasecki の優れた、非常に支持された答えです。


私自身もこれについて考えてきました。これまでの私のゆるい考えはここにあります、そして、私は他の人々がどう思うかと思っています。

xAL(および個人名を含む姉妹であるXNAL)は、GoogleとYahooの両方のジオコーディングサービスで使用されており、ある程度の重みがあります。しかし、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を許可するだけで、単一のデータベーステーブルにマップするのに十分簡単です。そして、これがAmazonや多くの組織が実際に住所データを保存する方法のようです。したがって、残っている問題は、プログラマやGUIコードで簡単に使用できるオブジェクトモデルでこれをどのようにモデル化するかです。 AddressAmericanAddressCanadianAddressなど、アドレスのタイプごとにサブクラスを持つベース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
}

実際、各国に個別の住所オブジェクトを持たせる代わりに、.NETプロパティを使用せずにAddressを使用して書式設定と検証を決定する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()メソッドアプローチを使用する理由は、コードがリフレクションまたはスイッチステートメントに頼ることなく、これらのフィールドを一般的な方法で実際に設定しやすくするためです。

プロセスが次のようになることを想像できます。

  1. GUIコードは、ファクトリメソッドなどを呼び出して、国に基づいて住所を作成します。 (したがって、国のドロップダウンは、顧客が最初に選択するものであるか、文化情報またはIPアドレスに基づいて事前に適切な推測が選択されています。)
  2. GUIはaddress.GetMetadata()または同様のメソッドを呼び出し、上記のAddressFieldMetadata構造のリストを受け取ります。このメタデータを使用して、表示するフィールド(is-applicablefalseに設定されているフィールドは無視)、それらのフィールドにラベルを付けるもの(field-nameメンバーを使用)、特定の順序で、そのデータに対して大まかなプレゼンテーションレベルの検証を実行します(is-requiredvalidation-regex、およびallowed-valuesメンバーを使用)。
  3. GUIは、field-number(上記の列挙に対応)とその指定された値を使用してaddress.SetField()メソッドを呼び出します。 Addressオブジェクトまたはその戦略は、これらのフィールドで高度なアドレス検証を実行したり、アドレスクリーナーを呼び出したりすることができます。

Addressオブジェクト自体を、作成後に不変オブジェクトのように動作させたい場合、上記にわずかなバリエーションがあります。 (Addressオブジェクトは実際にはデータ構造に似ており、おそらくそれ自体に関連付けられた本当の振る舞いをすることは決してないので、私はおそらくしようとします。)

これは理にかなっていますか? OOPパスから離れすぎていますか?私にとって、これは、実装がほとんど不可能(xAL)であるように抽象的であるか、厳密に米国に偏っているかの、かなり賢明な妥協を表しています。


2年後の更新:最終的にこれと同様のシステムになり、私のブログでそれについて書いた: http:// nicholas.piasecki.name/blog/2010/11/inside-skiviez-mailing-addresses/

このソリューションは、少なくともeコマースの世界にとって、レガシーデータとリレーショナルデータストレージの適切なバランスだと思います。

1