0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第3回 農薬データ構造設計から実装まで:NOULOG のデータ構造の思想

0
Last updated at Posted at 2026-04-29

過去回はこちらから
第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)まで、
実装の流れをまとめます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?