俺流テキストデータベース #9 リレーショナルデータベースにTRY

2018年12月1日

AWK jq データベース テクノロジー プログラミング 特集

データベースは、データ管理をするモノですが、独自テキストで行う事で、SQLの中身も理解できてきます。 そして、速度改善などのやり方をストレートに理解できるので、何も考えずにSQLコマンドだけを叩いているエンジニアの方は、是非データをモジュール依存せずに考えてみることをオススメします。 今回は、SQLでおなじみのリレーショナルをテキストデータベースで行ってみたいと思います。

テーブルデータの構築

SQLのテーブルにあたる、マトリクス配列にあたる縦横データを、郵便番号データを元に作ったjsonデータを使って構築していきます。 ファイルは全て"data"フォルダに格納するので、事前にdataディレクトリを作成しておきましょう。 郵便番号データベースをJSON変換して取得する方法

基本構造

- 都道府県マスターテーブル (prefecture.csv) - 市区町村マスターテーブル (city.csv) - それ以降の住所マスターデータ (town.csv) - 上記テーブルのIDをまとめた基本データテーブル (datas.csv) データ構造は、容量を軽くするために、csvを使って行います。 テーブルは「マスターテーブル」と「データテーブル」の2パターンで構成します。 マスターテーブルは「ID」「名称」のシンプルな構造で、データテーブルは「郵便番号,prefecture-id,city-id,town-id」のフィールド情報で構築します。

都道府県マスターの作成

jq -s -r -c '. | unique_by(.prefecture) | sort_by(.code) | .[] | [.prefecture] | @csv' ken_all_2.json | awk '{gsub("\"",""); print NR","$0}' > data/prefecture.csv

市区町村マスターの作成

jq -s -r -c '. | unique_by(.city) | sort_by(.code) | .[] | [.city] | @csv' ken_all_2.json | awk '{gsub("\"",""); print NR","$0}' > data/city.csv

予備住所マスターの作成

jq -s -r -c '. | unique_by(.town) | sort_by(.code) | .[] | [.town] | @csv' ken_all_2.json | awk '{gsub("\"",""); print NR","$0}' > data/town.csv

総合データ作成

データは上記のマスターを参照しながら、IDを書き込んでいく必要があるので、awkをファイルプログラムしておきます。 BEGIN{ FS=","; } # 県 FILENAME ~ /prefecture.csv/{ prefecture[$2] = $1; } # 市区町村 FILENAME ~ /city.csv/{ city[$2] = $1; } # その他 FILENAME ~ /town.csv/{ town[$2] = $1; } # 元データ FILENAME ~ /ken_all.csv/{ # 1.zip(postal) , 2.prefecture , 3.city , 4.town print $1","prefecture[$2]","city[$3]","town[$4]; } 上記をコマンドで実行 awk -f data-make.awk data/prefecture.csv data/city.csv data/town.csv data/ken_all.csv > data/datas.csv

データの呼び出し

マスターと基本データが整ったところで、郵便番号から、住所検索をしてみます。 これもマスター検索用にawkコードを事前に書いておきます。 ただこのプログラムで一括検索するのではなく、jqコマンドで、絞り込まれたデータをこのプログラムで、マスター検索して、IDを名称に変換します。 BEGIN{ FS=","; } { print $1; system("jq -Rcr 'split(\",\") | select(.[]==\""$2"\") | .[1]' data/prefecture.csv "); system("jq -Rcr 'split(\",\") | select(.[]==\""$3"\") | .[1]' data/city.csv "); system("jq -Rcr 'split(\",\") | select(.[]==\""$4"\") | .[1]' data/town.csv "); } jq -Rc 'split(",") | select(.[]=="1000001") | .' data/datas.csv | jq -rc '.|@csv' | tr -d '"' | awk -f load_data.awk 1000001 東京都 千代田区 千代田 jqコマンドのselectで絞り込んでいる箇所が郵便番号の7桁数値になるので、郵便番号に対して複数の住所結果がある場合は、その分の住所が表示されます。 今回は強引にリレーショナルに持っていきましたが、データベースも中はこのように、それぞれのデータのIDを繋げてデータ検索を行うという点では同じ動きであることが理解できれば、データベースの扱いスキルが向上できるでしょう。 それにしても、もう少し効率的に行いたいので、データ構造の見直しと、検索方法の見直しをやる必要がありますね。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ