🧩

Flutter--多対多炸裂のMySQLに中間tableを導入する苦難

2023/02/13に公開

大きな目標

データベースの構造にもSQL文にもなんの興味も知識もない不特定多数のuserが、flutter製のフロントサイドから、できるだけストレスなく情報を入力しつつ、縦横無尽に検索できるようなデータベースを構築する。

中期的な目標

NULL項目の多い1table構成を分解し、中間tableを導入して、多対多関係を整理する。
それがほんとうに良い設計かどうかは今は問わない。

今日の目標

userがdropdownButtonで選択したりTextFormFieldに入力したりした一連のvalue群から、内容に応じてinsertするtableを分別し、さらに複数のtableのlastInsertIDを取得して、中間tableに格納する。

  • 大変だったのは $*** で表されるvalueをSQL文に埋め込むこと。
  • syntax error頻発でお手上げ状態。
  • 中間table名やColumn名を犠牲にすることで単純化してなんとか乗り切る。
    • 中間tableは 二つのtable名を - で繋ぐ とか
    • カラム名は table名_idとする とか 見本に書いてあるとおりでは $*** が使えない
  • ただしこれは入力の方便なので、検索の時に有効に働くかはまだ不明。
    • とくにColumn名 period_id は本来 $period_idにしたかった。

できあがってみたら、実に単純

$*** 表記は一つにまで減らせたので、なんだ、これでいいのか、という感じ。

table名は $period-place と書きたかったがsyntax errorで
もちろん $periodplace もダメだが
ひっくり返して place$period が有効なのには驚いた。

なので、table名をここにもってくるまでが、試行錯誤の連続だったということ。

    // get period ID
    var lastInsertedPeriodID = resultEvent.lastInsertID;
    
    // get place ID
    var lastInsertedPlaceID = resultPlace.lastInsertID;
    
        // Insert $period_id and place_id into period-place table
    var resultPeriodPlace = await conn.execute(
        "INSERT INTO place$period (id, period_id, place_id) VALUE (:id, :period_id, :place_id)",
      {
        "id": null,
        "period_id": resultEvent.lastInsertID,
        "place_id": resultPlace.lastInsertID,
      },
    );
Flutter大学

Discussion