市区町村コード表(履歴付)を作成する .NET Core アプリを公開しました
2017年2月20日国勢調査等の市区町村別の統計データを過去から集計して比較しようとすると、平成の大合併により過去のデータは合併前の市町村のデータを集計する必要があり、普通に手作業ですると非常に手間のかかる作業になります。
政府統計の総合窓口(e-stat)の統計LODで、1970年以降の標標準地域コードのデータが公開されているので、それを利用して、任意の時点での市区町村コード表の作成や対応表が作成できるデータベースを作成するコンソールアプリケーションを作成しました。
.NET Core で作成したので、Windows だけでなく、Mac や Linux でも動作するし、.NET Core はインストールも手軽で簡単に動作させられるようになったので GitHub で公開してみました。URL は、以下のとおりです。
このアプリを作っていて気がついた点を2点メモしておきます。
コマンドラインの解析
コマンドラインの解析には、Microsoft.Extensions.CommandLineUtils を使いました。CommandLineUtils は、.NET Core になってやっと組み込まれた機能です。
以前の Microsoft はエンタープライズ向けのことには熱心なのですがシンプルに処理をするということにはあまり力が入っていなかったように思っていましたが、.NET Core、ASP.NET Core になって、シンプルに作りたい場合にも使いやすくなったと思います。コマンドラインの解析は、簡単そうですが実際に自分で作るとなると結構手間がかかるので、.NET Core になって改善された典型的な例だと思います。
コード表の処理速度
作成した市区町村コードのデータは、json形式にしています。例えば、期間付き市区町村コードは以下のような形式になっていて、4588件のレコードがあります。
public class StandardAreaCode { [JsonProperty("id")] public int Id { get; set; } public string 名称 { get; set; } public string ふりがな { get; set; } public string 英語名 { get; set; } public 自治体種別 種別 { get; set;} //北海道、東京都島嶼部、長崎県対馬(旧)は支庁・振興局、その他の町村は郡、区は政令指定都市のコード public int 所属 { get; set; } //北海道及び旧長崎県対馬支庁の町村のみ public string 郡名称 { get; set; } public string 郡ふりがな { get; set; } public DateTime 施行年月日 { get; set; } public DateTime 廃止年月日 { get; set; } public List<int> 施行データ { get; set; } public List<int> 廃止データ { get; set; } }
これらのデータを Web アプリケーションの中で使う時に、RDB にインポートするのは面倒なので、メモリーベースで処理をするということで、処理時間を計測してみました。都道府県毎に市区町村コードの一覧を計算する処理で、画面の例は「北海道の市区町村コード一覧」です。また、一覧を計算するコードのメインは以下のようになっていて、LINQ を使うのであれば、リストや配列の場合でも SQL Server を使うのとほぼ同じコードで書くことができます。
public IEnumerable<(int id, string 名称, string ふりがな)> GetAreaCode(int pref, DateTime date) => AreaCodeList .Where(x => x.Id / 1000 == pref && x.施行年月日 <= date && x.廃止年月日 > date && x.所属 != 99) .Select(x => (id: x.Id, 名称: x.名称, ふりがな: x.ふりがな)) .OrderBy(x => x.id);
Google Compute Engine の n1-standard-2 (AWS の m4.large とほぼ同性能)を使って処理時間を計測すると以下のようになりました。
- ファイルサイズ 1126KB
- データの読み込み時間 45ms
- 計算時間 0.4~0.008ms
結果としては、SQL Server Express を使うよりも遙かに早いです。計算時間の 0.4ミリ秒は初回の計算の時で計算ルーティンやデータが CPU のキャッシュメモリーに入っていない場合の処理時間です。計算の必要なコードとデータが CPU のキャッシュメモリにキャッシュされてしまえば 0.008ms という圧倒的な速さで処理がなされます。こういう処理ではデータのやりとりにばっかり時間を食っていて、本当の計算時間なんてごく僅かのものだなと感じます。
そういうことで、データー量がそれほど大きくないコード関係は RDB を使うのをやめてメモリーに乗せていこうと思っています。管理も、RDB で管理するよりも、テキストベースにして git で管理した方が遙かに管理しやすいし、入力もデータベース用の入力画面を使うよりも、テキストエディターや Excel で編集できた方が楽です。RDB をやめることの欠点ってといえば、コードを修正する毎にアプリをデプロイしなければいけないので、その手間が増えるのですが、昔と違って今はデプロイが楽になっているのでデータの更新の頻度ににもよりますがそれほどの負担にはならないと思います。