住所の郵便番号データの前処理について

用意するもの

郵便番号データの仕様

まずは、データの仕様の確認から。
住所の郵便番号データはCSV形式(カンマ区切り形式)で提供されています。
下の表、注記とデータの格納イメージは郵便事業株式会社の「郵便番号データの説明」から抜粋しました。

カラム 内容 データ型
1 全国地方公共団体コード(JIS X0401、X0402)半角数字
2 (旧)郵便番号(5桁) 半角数字
3 郵便番号(7桁) 半角数字
4 都道府県名 半角カタカナ(コード順に掲載) (注1)
5 市区町村名 半角カタカナ(コード順に掲載) (注1)
6 町域名 半角カタカナ(五十音順に掲載) (注1)
7 都道府県名 漢字(コード順に掲載) (注1,2)
8 市区町村名 漢字(コード順に掲載) (注1,2)
9 町域名 漢字(五十音順に掲載) (注1,2)
10 一町域が二以上の郵便番号で表される場合の表示 (注3) (「1」は該当、「0」は該当せず)
11 小字毎に番地が起番されている町域の表示 (注4) (「1」は該当、「0」は該当せず)
12 丁目を有する町域の場合の表示 (「1」は該当、「0」は該当せず)
13 一つの郵便番号で二以上の町域を表す場合の表示 (注5) (「1」は該当、「0」は該当せず)
14 更新の表示(注6)(「0」は変更なし、「1」は変更あり、「2」廃止(廃止データのみ使用))
15 変更理由 (「0」は変更なし、「1」市政・区政・町政・分区・政令指定都市施行、「2」住居表示の実施、「3」区画整理、「4」郵便区調整等、「5」訂正、「6」廃止(廃止データのみ使用))

※1 文字コードには、MS漢字コード(SHIFT JIS)を使用しています。
※2 文字セットとして、JIS X0208-1983を使用し、規定されていない文字はひらがなで表記しています。
※3 「一町域が二以上の郵便番号で表される場合の表示」とは、町域のみでは郵便番号が特定できず、丁目、番地、小字などにより番号が異なる町域のことです。
※4 「小字毎に番地が起番されている町域の表示」とは、郵便番号を設定した町域(大字)が複数の小字を有しており、各小字毎に番地が起番されているため、町域(郵便番号)と番地だけでは住所が特定できない町域のことです。

<小字に同一番地が存在する住所>○○市△△町が郵便番号の表す範囲であり、町域(郵便番号)と番地だけでは住所が特定できません。
○○市△△町字A100番地
○○市△△町字B100番地
○○市△△町字C100番地

※5 「一つの郵便番号で二以上の町域を表す場合の表示」とは、一つの郵便番号で複数の町域をまとめて表しており、郵便番号と番地だけでは住所が特定できないことを示すものです。
※6 「変更あり」とは追加および修正により更新されたデータを示すものです。
※7 全角となっている町域名の文字数が38文字を超える場合、また、半角カタカナとなっている町域名のフリガナが76文字を越える場合には、複数レコードに分割しています。

データの格納イメージ

データの格納イメージ 各項目は、半角の「,」(カンマ)で区切っており、上記の2)~9)までの項目は「”」(ダブルクォーテーション)で囲んでいます。
上記4)~9)までは可変長形式であり、空白のない形式です。
1レコードの区切りは、キャリッジリターン(CR)+ラインフィード(LF)です。
9)の項目位置に、「”以下に掲載がない場合”」とは、お探しの町域が見つからない場合にお書きいただく番号であり、町域を特定するものではありませんのでご注意ください。
9)の項目位置に、「”○○市(または町・村)の次に番地がくる場合”」とは、市区町村名の後ろに町域名がなく、番地がくる住所(例:○○郡△△町1234番地)の場合にお書きいただく番号です。
9)の項目位置に、「”○○市(または町・村)一円”」とは、町域名がない市区町村の場合にお書きいただく番号です。

データ処理方法の決定

使いやすいデータに変換するために以下の処理を行う。
(注記の内容を把握するのに一苦労・・・。)

  1. 文字コード ・・・ 仕様※1参照。MS漢字コード(SHIFT JIS)からUTF-8に変換
  2. 文字セット ・・・ 仕様※2参照。いちいち漢字に変換していられない。ひらがなでも住所としては問題ないので、そのまま使用する。
  3. 半角カナ ・・・ 全角カナに変換
  4. カンマ区切り ・・・ タブ区切り(TSV)に変換(TSVのほうが何かと扱いやすいので)
  5. カラム10 ・・・ 仕様※3参照。カラム10=1のものは、町域名で特定できないため、町域名に括弧書き()がされているものがある。例)”大通り西(1~19丁目)”。括弧書きがあるものは、括弧書き内の文字を別カラム(後述)に移動させる。しかし、カラム10=0の場合も括弧書きがあるものがある。例)**ビル(10階) よって、フラグだけでは、判別不能?
  6. カラム11 ・・・ 仕様※4参照。カラム11=1のものは小字に同一番地が付定されている場合で、町域(郵便番号)と番地だけでは住所が特定できない町域。平成19年8月31日版では該当なし。処理も特に必要なし。
  7. カラム12 ・・・ 丁目の有無。処理なし。
  8. カラム13 ・・・ 仕様※5参照。カラム13=1のものは、一つの郵便番号で二以上の町域を表す場合。
  9. カラム14,15 ・・・ 仕様※6参照。更新用フラグのため、処理なし。
  10. ※7 ・・・ 処理方法だけ書くと、町域名に”(”と”)”が含まれるものは別のカラム(備考、コメントなど)を用意してそこに移動させる。町域名に”(”だけが含まれるものは分割されているので残りのレコードとマージして、括弧内の文字を同様に別カラムに移動させる。*1
  11. データの格納イメージの記載事項から ・・・ 町域名に対しての処理
    1. 町域名が「”以下に掲載がない場合”」の場合、町域名の値は空(””)にする
    2. 町域名が「”○○市(又は町・村)の次に番地がくる場合”の場合、町域名の値は空(””)にする
    3. 町域名が「”○○市(又は町・村)一円”」の場合、町域名の値は空(””)にする

*1) 仕様と実際の運用が異なっていたりしています。この処理方法はデータの中身を検証した上での判断ですが十分かどうか・・・。

まとめ

結局まとめると以下の6つ。

  1. 文字コードはUTF-8に変換する
  2. 半角カナを全角カナに変換する
  3. CSVをTSV(タブ区切り形式)に変換する
  4. 町域名に”以下に掲載がない場合”、”の次に番地がくる場合”、”一円”の文字が含まれる場合、町域名の値は空(””)にする
  5. 括弧書きの保管場所として"備考"カラムを追加する
  6. カラム10のフラグに関係なく、町域名の括弧書きは"備考"カラムに移動させる。複数レコードに分割されている場合は、マージする。 詳細は上記”データ処理方法の決定”の10を参照のこと。

テーブルの設計

テーブルには公開されている郵便番号データにidカラムと括弧書きの内容を入れるためのcomment_k,commnet_jカラムを追加。カラム10~15は更新用フラグなので削除。

カラム名 データ型 備考
id int キー
pubcode int 全国地方公共団体コード
zip5 char(5) (旧)郵便番号(5桁)
zip7 char(7) 郵便番号(7桁)
pref_k text 都道府県名カタカナ
city_k text 市区町村カタカナ
town_k text 町域名カタカナ
comment_k text 備考カタカナ(括弧書き内の文字)
pref_j text 都道府県名
city_j text 市区町村
town_j text 町域名カタカナ
comment_j text 備考(括弧書き内の文字)

変換処理

郵便番号データのCSVから上のDB作成までを行うスクリプトを作成する。
変換用スクリプトはお好みの言語で。
データベースには手軽なSQLite3を使用しました。
他のDBで使用したい場合はダンプファイルを利用すればいいだけなので。
(変換処理のスクリプトは今のところ公開していません。)

SQLiteにはコマンドラインツールがついていますが、GUIの管理ツールがあると何かと便利なのでついでにご紹介。
SQLiteStudio non-commercial version

ちなみに、ここで作成したDBは
Adobe AIRを使った住所検索アプリ
で使用しています。