過去回はこちらから
第1回 https://qiita.com/tuyomori/items/95ce38547491c5547586
第2回 https://qiita.com/tuyomori/items/28230af0b8b4adcf7f19
次回
番外編 https://qiita.com/tuyomori/items/98a00d153697c8116ac8
■ NOULOG は「農薬データベース」ではない
ここを最初にハッキリさせたい。
世の中にはすでに農薬データベースがあります。
農薬取締法に基づく登録情報
メーカーの適用表
病害虫別の検索サイト
成分・RACコードの一覧
これらは “農薬そのものの情報を網羅するためのデータベース” です。
しかし NOULOG がやりたいのは まったく別のこと。
■ NOULOG の目的は「農薬選定の意思決定を支援すること」
農薬データそのものを網羅したいのではなく、
過去の散布記録
作物ごとの履歴
成分のローテーション(RAC)
使用回数の累積
在庫
現在の病害虫状況
こうした “現場の文脈” と農薬データを掛け合わせて、
その時点で最適な農薬を選ぶための判断材料を出すこと が目的。
つまり NOULOG は、
農薬データベース × 農家の散布履歴 × 現場の状況
= 意思決定支援システム
これが本質。
■ なぜ農薬データを“そのまま”使えないのか
理由はシンプルで、
農薬データは「意思決定に使うには複雑すぎる」から。
実際の生データ(モベントフロアブル抜粋)を見ると分かる。
この構造は 人間にも機械にも扱いづらい。
スマホアプリで扱うには重いし、更新のたびに巨大 JSON を再生成する必要がある。
NOULOG では、この問題を根本から避けるために、
「ネストしないデータ構造」=“テーブルを分けてフラットにする” という方針を採用した。
■ 実際の生データを見ると「ネスト地獄」がよく分かる
例えば、モベントフロアブルの適用表を一部抜粋するとこうなる:
| 作物名 | 適用病害虫 | 希釈倍数 | 使用方法 | 使用時期 | 使用回数 | 散布液量 |
|---|---|---|---|---|---|---|
| さといも | アブラムシ類 | 2000倍 | 散布 | 収穫7日前まで | 3回以内 | 100~300L/10a |
| アブラムシ類 | 24倍 | 無人航空機 | 収穫7日前まで | 3回以内 | 3.2L/10a | |
| ハダニ類 | 2000倍 | 散布 | 収穫7日前まで | 3回以内 | 100~300L/10a | |
| ばれいしょ | アブラムシ類 | 4000倍 | 散布 | 収穫7日前まで | 3回以内 | 100~300L/10a |
| だいこん | コナガ | 2000倍 | 散布 | 収穫7日前まで | 3回以内 | 100~300L/10a |
CSVに加工
さといも,アブラムシ類,2000倍,散布,収穫7日前まで,3回以内,100~300L/10a
,アブラムシ類,24倍,無人航空機,収穫7日前まで,3回以内,3.2L/10a
,ハダニ類,2000倍,散布,収穫7日前まで,3回以内,100~300L/10a
ばれいしょ,アブラムシ類,4000倍,散布,収穫7日前まで,3回以内,100~300L/10a
だいこん,コナガ,2000倍,散布,収穫7日前まで,3回以内,100~300L/10a
これを素直に JSON にすると:
作物ごとに病害虫が複数
病害虫ごとに希釈倍率が複数
使用方法も複数
散布液量も複数
使用回数制限も複数
つまり 多重ネストの沼 になる。
さらに、作物名が省略されている行(=前行の作物を引き継ぐ)も混ざっているため、
人間が読んでも複雑、機械が扱うともっと複雑。
■ NOULOG の方針:ネストを避けて“分解”する
この生データをそのまま JSON にすると破綻するので、
NOULOG では 役割ごとにテーブルを分けてフラット化 した。
■ NOULOG のテーブル構造(確定版)
① pesticide_master(農薬マスター)
農薬そのものの基本情報。
pesticide_master
- id
- pesticide_id
- regist_num
- name
- formulation
- category
- toxicity_class
② ingredient_master(成分マスター)
成分は農薬と独立して更新されるため、最新版だけ保持。
ingredient_master
- id
- name
- rac_codes
- category
- origin
- organic_general
- organic_reason
③ pesticide_ingredient_relation(農薬 × 成分)
農薬と成分の紐づけ。
pesticide_ingredient_relation
- id
- pesticide_id
- ingredient_id
- percentage_label
- percentage
④ pesticide_application(農薬 × 作物/使用場所)
農薬がどの作物に使えるか。
pesticide_application
- id
- pesticide_id
- crop_name
- usage_area
UNIQUE (pesticide_id, crop_name, usage_area)
⑤ pesticide_pest(農薬 × 作物 × 病害虫 × 使用条件)
生データの「1行」をそのまま1レコードに落とし込むテーブル。
pesticide_pest
- id
- pesticide_id
- crop_name
- usage_area
- pest_name
- dilution_label
- dilution_ratio
- usage_method
- usage_timing
- limit_label
- limit_count
- water_amount_label
- water_amount
- notes
生データのように「作物名が省略されている行」も、
ここでは 前行の crop_name を補完して1行=1レコード にできる。
⑥ change_log(差分テーブル)
NOULOG の心臓部。
すべての変更履歴を一元管理。
change_log
- id
- source_version
- table_name
- record_id
- change_type (enum)
- pesticide_id
- note
- updated_at
■ この構造が実現すること
✔ ネストなしで軽量
✔ CSV と相性が良い
✔ 部分更新が簡単
✔ 過去版の再現ができる
✔ スマホアプリで高速
✔ 人間でも修正しやすい
つまり、
この複雑な生データを、
“現場で扱える形” に落とし込んだのが NOULOG の農薬データ構造です。
構造が決まったので、次の第4回では 実際に生データをどう加工して、
この構造に流し込むのか を解説します。
CSV → JSON → 更新管理(source_version / change_log)まで、
実装の流れをまとめます。