有田市ふるさと納税:SBM配分最適化エンジン (ローカライズ版)
① 同一寄付者まとめ重視 50
同じ寄付者の注文が別々の農家や別々の日に出荷される(クレームの原因)のを防ぐ。
0: 無視100: 絶対揃える
② 農家さじ加減(ひいき) 50
新人農家へ優先的に割り当て、クレームの多い農家を避ける政治的配慮。
0: 公平配分100: 新人集中
③ 明日へのバッファ 50
今日の出荷キャパを限界まで使わず、明日のために余力を残す職人の勘。
0: 限界まで(100%)100: 余裕残し(80%)
④ 農家パニック回避 50
1つの農家に5kg箱と10kg箱が入り乱れて梱包作業が混乱するのを防ぐ。
0: 無視100: サイズ統一
最適化計算中...
農家への割り当て状況

実行ボタンを押してください。

見送り(明日以降へ回す)

0

実行時間: - ms
最終ペナルティエネルギー: -
全注文 (箱) 割り当てリスト
注文ID 寄付者ID サイズ 割当先農家
実行ボタンを押してください。
登録農家マスタ
ID農園名キャパ属性
登録注文マスタ (現場未割当)
注文ID寄付者IDサイズ

アーキテクチャ比較:なぜ「つなげモン(SBM)」なのか?

従来のSQL/IF文による個別開発と、完全縦持ちDB×SBM方式の決定的な違い

従来アプローチ

SQL × アプリ側での貪欲法(IF文)

① 初期開発コスト

❌ 膨大・泥臭いスパゲティコード

「A農園優先」「同一寄付者は同日」等の条件を幾重ものIF文や入れ子のループ、重いJOINで書き下す必要があり、ロジックが肥大化する。

▼ 現場のドロドロを表現しようとした地獄のSQL例
SELECT order_id, 
  CASE 
    WHEN f.is_newbie = 1 AND o.box_size = '5kg' THEN 'farmer_B'
    WHEN (SELECT COUNT(*) FROM orders o2 
          WHERE o2.donor_id = o.donor_id) > 1 
         AND o.box_size = '10kg' THEN 'farmer_A'
    /* ここから無限に続く条件分岐とJOINの嵐... */
    ELSE 'pending'
  END as assigned_farmer
FROM orders o LEFT JOIN farmers f ON ...
② データ構造(連動面)

❌ 横に広がる(テーブルカラムの増加)

新しいルール(新人フラグ、要注意フラグ等)が出るたびに基幹DBにカラムを追加。既存のシステム間連携IF(インターフェース)を破壊する。

③ 新ルールの追加(保守性)

❌ 再開発・再デプロイ・全結合テスト

「夏モードを追加」となったらソースコードを書き換えて再コンパイル。他のロジックが先祖返りやバグを起こしていないか、全テストが必要。

④ システムのタフさ

❌ 次元の呪いによるタイムアウト

データ量や制約が1つ増えるだけでSQLの実行計画が狂い、処理時間が指数関数的に跳ね上がっていつかフリーズする。

つなげモン・コア

完全縦持ちDB × SBM(数理モデル)

① 初期開発コスト

⭕️ 極小(基盤は1週間で実装可能)

アプリ側はDBの値を数式(ペナルティ関数)に変換してSBMに投げるだけ。ロジック自体を条件分岐(IF文)でガチガチに作り込む必要がない。

▼ SBMの評価関数(ペナルティを足すだけ)
// 状態(割り当て先)が渡されるのでペナルティを計算するだけ
let mut penalty = 0.0;

// 同一寄付者のバラバラ出荷ペナルティ
if donor_assignments.len() > 1 {
    penalty += (donor_assignments.len() - 1) as f64 * weight_donor;
}

// 新人ひいきボーナス
penalty -= farmer.is_newbie as f64 * count * weight_farmer_bias;

// ... あとはSBMが勝手に全体最適を計算し尽くす!
② データ構造(連動面)

⭕️ 縦に伸びる(データ行の追加のみ)

ルールも変数もすべて単一の共通テーブルの「行」で吸収。既存システムとデータをやり取りする連携IFは最初から最後まで1ミリも変わらない

③ 新ルールの追加(保守性)

⭕️ ノンストップ(開発改修ゼロ)

管理者画面からDBに「夏フラグ: 1」の行を1行 INSERT するだけで即時対応。プログラムの変更も、再デプロイも、再起動すら不要。

④ システムのタフさ

⭕️ 爆速・ミリ秒単位でスケール

計算はsqlxでロードしたRustのメモリ上で完結。SBM(模擬分岐法)なので、どれだけ変数や制約が増えてもフリーズせずコンマ数秒でタフに解き切る。

結論:既存システムを1ミリも汚さない「DB to DB」のステートレス設計

基幹DBからデータを吸い上げ、Rustが1秒でパズルを解き、結果を書き戻して即座に終了する。常駐もしないためバグの入りようがない。だから「連動システム」側の改修コストも極限まで引き下げられます。