郵便番号DBを利用するときに考慮すると幸せになれること

郵便番号DBを利用するときに考慮すると幸せになれること

はぁ?

Studio JamPack Public DB 郵便番号データベースについて、クエリを投げる場合に考慮すべき点をまとめてみました。開発をする人は読むと幸せになれるかもしれません。

郵便事業株式会社のデータは完全なデータではない

郵便事業株式会社の公開している郵便番号データダウンロードサービスでは、CSVを公開していますが、これを利用するに当たってそのまま利用できないことが指摘されています。

  • 住所の郵便番号と大口事業所個別番号が別データとなっている件
  • 全国地方公共団体コードが規格に沿っていない件
  • 1レコードが複数レコードに分割されている件

これらの理由や詳しい情報は https://jamfunk.jp/wp/?p=390

このため、郵便事業株式会社のデータを改良して利用する必要があり、JPDBやZipCloudさんのようなデータ提供サービスが必要になります。

差分データを収録すべきである

データとしては現行データのみの提供で十分ですが、実際にサービスに組み込んで利用する場合は差分データを収録すべきです。
例えばユーザ登録や発送先の入力をする際に、以下の例が考えられます。

  • 郵便番号はあっているけど、住所が間違っている人。
    →現行データだけで十分に対応できます。
  • 郵便番号が間違っている人
    →住所よみからの検索で対応できます。
  • 古い郵便番号や住所で覚えている人
    →差分データを利用して、郵便番号が廃止になったり、住所が変更になっていることを知らせる必要があります。

全国地方公共団体コードをチェックデジット(CD)1桁を含めていない

何の役に立つか知りませんが、規格は従うべきで、チェックデジットを含めた6ケタ表記とすべきです。ただ、それだけです。(^^;

データ構造の注意点

本JPDBは、前項でも書いたとおり、差分データを含んでいます。
そのままクエリを引くと、flag_update=’2’の廃止データも引っ張ってきますので、その点を考慮してください。
住所候補入力として使用する際は、flag_update!=’2’とするか、flag_update=’2’の場合は「廃止」と表示したり赤くしたりしてその番号やデータが既に使われていないことを利用者に明示し選択できないようにしてください。

町域で複数の町域を含む場合は、「共通の町域(複数の町域または丁目~丁目・番地~番地)」のような表記がなされています。
そのため、検索候補を表示するときはそのまま県・市区町村郡・町域・番地・事業所名を表示しますが、候補を入力欄に代入(転記)する場合は町域の括弧を省くことが望ましいようです。
特に、町域によっては250文字ほどに及ぶレコードがあるため、ユーザに削除させるのは些か困難かと思われますし、万が一削除しないまま入力された場合は郵便物に添付するラベルを印刷する場合に支障を来すかもしれません。
ただし、事業所個別番号(flag_type!-‘-‘)の場合は、私書箱番号や階数表記がほとんどのため、そのまま括弧ごと代入した方がよいかもしれません。

表記用テーブル

JPDBでは各flag項に対して表記用の文字列を納めた表記用テーブルを設けています。
flag項を表示する場合はこのテーブルを利用してみてはいかがでしょうか。

出てくるデータのパターン

作業を行っていたり、データを利用していた際に見つけたいくつかのパターンをあげておきます。たまたま見つけたモノですので、他にも妙なパターンが見つかるかもしれません。

1つのクエリに1つのレコードが返ってくる

zipcode addr_pref addr_city addr_town
8140143 福岡県 福岡市城南区 南片江

一般的な例です。

1つのクエリに2つ以上のレコードが返ってくる

zipcode addr_pref addr_city addr_town
8070042 福岡県 遠賀郡水巻町 吉田
8070042 福岡県 遠賀郡水巻町 吉田団地

flag_1town2code=’1’(1郵便番号に複数の町域)になっているレコードの典型的なパターンです。

zipcode addr_pref addr_city addr_town
8160812 福岡県 春日市 平田台
8160812 福岡県 大野城市 平田台

同様に flag_1town2code=’1′ になっているが、町域が同じで複数の市にまたがっているパターンです。

1つのクエリに2つ以上のレコードが返ってくるが、廃止レコードが含まれている

zipcode addr_pref addr_city addr_town addr_town_kana flag_update flag_reason update
8190053 福岡県 福岡市西区 城の原団地 ジヨウノハルダンチ 1(変更) 5(訂正) 2008/11/26
8190053 福岡県 福岡市西区 城の原団地 ジヨウノハラダンチ 2(廃止) 6(廃止) 2008/11/26

町域の読みが変わった例です。その他に市町村合併や事業所名変更などのパターンで廃止と変更が一緒に含まれていることが良くあります。

町域がやたら長い(括弧表記されている)

zipcode addr_pref addr_city addr_town
8260043 福岡県 田川市 奈良(青葉町、大浦、会社町、霞ケ丘、後藤寺西団地、後藤寺東団地、希望ケ丘、松の木、三井後藤寺、緑町、月見ケ丘)

データにはこのような1つのレコードで複数の町域を収録するパターンと、複数レコードに同一郵便番号で複数の町域を収録するバターンがあります。基準は不明です。個人的には後者のレコード数が多くなってもデータ長を短くして欲しいのですが。。。

zipcode addr_pref addr_city addr_town
6028368 京都府 京都市上京区 北町(上の下立売通天神道西入上る、上の下立売通御前西入、上の下立売通御前西入上る、上の下立売通御前西入2丁目、上の下立売通御前西入2筋目、下長者町通御前西入、天神道上の下立売上る、天神道仁和寺街道下る、天神道下立売上る、天神道妙心寺道上る、天神道妙心寺道上る西入、仁和寺街道天神道西入下る、仁和寺街道天神道東入下る、御前通上の下立売上る、御前通上の下立売上る西入、御前通下立売上る、御前通下長者町上る西入、御前通仁和寺街道下る西入、御前通妙心寺道上る西入、御前通西裏上の下立売上る、御前通西裏下立売上る)

もう何が何だかよく分からない例。しかも、郵便事業のaddr_town_kana(町域名半角カタカナ)データは漢字と全く違ったデータが入っており、JPDBの処理アルゴリズムでは「キタマチキタマチキタマチキタマチキタマチキタマチキタマチキタマチ」と、さらに誤ったデータが生成されてしまい、狂気を感じるパターン(^^; ちなみにこのパターンは「6028374」の「京都府 京都市上京区 西町(・・・」、「6020816」の「京都府 京都市上京区 毘沙門町」などの、「京都市上京区」で多く見られる。郵便事業に改善を要求したい。(2012年8月)

廃止レコードが複数ある

zipcode addr_pref addr_city addr_town addr_town_kana flag_update flag_reason update
8191131 福岡県 糸島市 篠原 シノワラ 1(変更) 1(行政施行) 2009/11/26
8191131 福岡県 前原市 篠原 シノハラ 2(廃止) 6(廃止) 2008/09/30
8191131 福岡県 前原市 篠原 シノワラ 2(廃止) 6(廃止) 2009/11/26

3行目から2行目へ町域名の読みが変更され、2行目から1行目へ市町村合併で変更になったパターンです。
事業所も会社名が二転三転したり、市町村合併や管轄郵便局の変更で変更になるパターンも多いようです。

同じ町域でも郵便番号が異なる

zipcode addr_pref addr_city addr_town
8190166 福岡県 福岡市西区 横浜(1~2丁目)
8190366 福岡県 福岡市西区 横浜(3丁目)

丁目毎に郵便番号が異なるパターンです。

zipcode addr_pref addr_city addr_town
8190033 福岡県 福岡市西区 橋本(大字)
8190031 福岡県 福岡市西区 橋本(丁目)

丁目を有する場合と有しない場合もあるようです。
ちなみにこのパターンでは flag_chome はどちらも1でした。

zipcode addr_pref addr_city addr_town addr_num office_kanji flag_num
8108655 福岡県 福岡市中央区 清川 2丁目22-8 株式会社 福岡放送 1
8108656 福岡県 福岡市中央区 清川 2丁目22-8 株式会社 福岡放送 2

2つの郵便番号をどう使い分けているのか知りませんが、1事業者で最大3つの個別番号を持っているパターンがあります。

やたら大量の件数を返す

zipcode addr_pref addr_city addr_town
4520961 愛知県 清須市 *

67愛知県清須市の各町域67件を返します。うち1件は廃止データです。(2012年8月)

ちなみに町域→郵便番号の逆引きだと「本町」が630件です。「以下に掲載がない場合」だと1987件返ってきます。(2012年8月)

新たなパターンを見つけたら追記するかもしれません。

郵便番号データについて思ったこと

郵政事業株式会社(日本郵政)郵便番号データについて、思ったこととか分かったこととか

この投稿は

 郵政事業株式会社(日本郵政)の公開している郵便番号データ(http://www.post.japanpost.jp/zipcode/download.html)について、すながわがJamPack Public DB(https://jamfunk.jp/wp/?page_id=353)を立ち上げるときに分かったこととか、思ったことを勝手に書き連ねています。

 あくまでも勝手なので、本当は違っていたり、検証をしていないような無責任なことを書いているかもしれません。

郵便番号データはそのままお召し上がりにはなれません

 郵政事業株式会社の郵便番号データは、CSVをそのままインポートするだけでは正確なデータベースにはなりません。
理由は以下の通り。

  1. 住所の郵便番号と大口事業所個別番号が別データとなっており、カラム設計が異なっている。
  2. 全国地方公共団体コードは規格上はチェックデジット1ケタを含めた6ケタでないといけないが、郵便番号データ(住所・事業所それぞれ1カラム目)は5ケタになっており、チェックデジットが省略されているため。
    また、事業所データのうち、廃止されたコードのままになっているデータがある。
  3. 1レコードが複数レコードに分割されているため。

住所の郵便番号と大口事業所個別番号が別データとなっている件

 せっかく検索できるようにするなら、1テーブルですべて検索をできるようにすべきである。

 よって、結論は簡単だが、住所と事業所のカラムを統一し、マージすればよい。
結果はこれ(データ構造の項のzipcode_f_01)

 ちなみにJPDBは差分データ(追加・廃止)もすべて含めました。利用者に住所や郵便番号の変更を知らせることにも利用できます。
住所事業所一元化と差分データ包括という点でzipcloudさんよりも2歩先行きました(^ー^)

全国地方公共団体コードが規格に沿っていない件

 個人的に使っている他のデータベースと連携するため、必要だったので調べてみました。
 全国地方公共団体コードは、1~2ケタ目が都道府県コード(JIS X0401)、3~5ケタ目が市区町村コード(JIS X0402)、6ケタ目がチェックデジットと定められています(http://www.soumu.go.jp/main_content/000137948.pdf)。
 しかし、郵便番号データでは5ケタしかなく、チェックデジットが省略されています。

 よって、チェックデジットを含めた6ケタで運用すべきであり、全国地方公共団体コードのチェックデジットを算出して付加すればよい。
結果はこれ。

コードABCDEの場合
(A×6+B×5+C×4+D×3+E×2)÷11 = F あまり G、11-G=E、Eの1の位がCD

 SQLで表すと、これ。

UPDATE `zipcode_f`
  SET `pref_jis` = CONCAT(
    `pref_jis`,
    substr(
      11 – (
        substr(`pref_jis`, 1, 1) * 6 +
        substr(`pref_jis`, 2, 1) * 5 +
        substr(`pref_jis`, 3, 1) * 4 +
        substr(`pref_jis`, 4, 1) * 3 +
        substr(`pref_jis`, 5, 1) * 2
      )
      % 11, -1, 1
    )
  )
  ;

1レコードが複数レコードに分割されている件

 これが一番やっかい。
「郵便番号から住所を検索するサービスにまともなものがない – ぐるぐる~」(http://d.hatena.ne.jp/bleis-tift/20080531/1212217681)や、「郵便番号データの落とし穴 – YU-TANG's MS-Access Discovery」(http://www.f3.dion.ne.jp/~element/msaccess/AcTipsKenAllCsv.html)で報告されている。

 郵便番号データのうち、住所データは町域かな(6カラム目)または町域(9カラム目)が「 全角となっている町域名の文字数が38文字を超える場合、また、半角カタカナとなっている町域名のフリガナが76文字を越える場合には、複数レコードに分割」と記載してあります。

 この現代にそぐわないデータ形式は郵便事業株式会社で大昔に利用していた汎用機の名残だと勝手に察します。郵便事業株式会社にはもっと効率的なデータを提供いただけることを要望しますが、仕様変更を行うには多くの既存ユーザを巻き込まないといけないため、行えない現状も勝手に察します。

 しかも分割の定義をしているにもかかわらず、規定の文字数を超過するところ、規定の文字数内でも分割されている場合もあるようです。

 ちまたの郵便番号データを活用したがっているサイトではこの事実を知って理解している人は意外と少なく、インポートのみで「ほら簡単でしょ」とのたまうサイトが多いのが現状です。

 この問題を解決するには、前述のサイトでいろいろ考察されていますが、郵政事業株式会社は公式な手法を公開していません。
そこで、前述サイトの方法を拝借し、以下のアルゴリズムで対応させました。

  1. 郵便事業株式会社郵便番号データのうち、住所番号を順序通り1行ずつ読み込む。
  2. 「町域」で、"("が含まれ、")"が含まれないデータを検索する。
  3. 当該のデータを見つけた場合、そのデータより先にあり、「郵便番号」が等しく、"("が含まれず、")"が含まれるデータを検索する。
  4. それらのデータの「町域かな」と「町域」をそれぞれ順序通り結合する。
  5. 結合したデータに置き換える。

 このアルゴリズムは前述の2サイトと「郵便番号データの廃止データを解析してみた – my-hobby」(http://www.my-hobby.jp/index.php/category/postal-code-lookup/)を参考にさせていただきました。

2012.08.12追記
「町域」に括弧が含まれても「町域かな」には括弧が含まれないレコードが確認されたので、判定は「町域」で行うことにしました。

 なお、生成結果を流し読みはしましたが、未検証です(^^; YU-TANGさんの「0285102」と「8260043」の2件のチェックは行っております。

参考