開発Tips

Flutter版ログ簿でローカルDBに ObjectBox を選んだ理由

前回の記事では、ネイティブ Android から Flutter へ移行した全体像を書きました。その中でローカルDBに ObjectBox を採用しています。この記事では、「なぜ ObjectBox だったのか」を掘り下げます。

Flutter のローカルDBというと、まず sqflite(SQLite)や drift(SQLite ベースのORM)が候補に挙がります。それでも ObjectBox を選んだのは、次の3つの理由からでした。

理由1: ネイティブAndroid時代から使っていた

いちばん大きかったのは、移行元のネイティブ Android 版が、すでに ObjectBox を採用していたことです。

DBエンジンが同じなら、データ構造の考え方をそのまま持ち込めますし、旧Androidデータの移行も「別エンジンへの変換」ではなく「同じエンジンの引っ越し」として考えられます。ゼロから SQLite 系に載せ替えると、スキーマ設計とデータ移行を両方作り直すことになり、移行のリスクと工数が増えます。既存の資産と地続きにできる——これが最初の決め手でした。

理由2: SQLite ベースの構成より軽量・高速に扱える

ObjectBox は、行と列のテーブルではなく オブジェクトをそのまま保存する 組み込みDBです。

SQLite(や、その上に載る ORM)を使う場合、

  • オブジェクト → SQL 文 → テーブルの行、というマッピング層
  • クエリ結果 → 行 → オブジェクト、という逆マッピング

が挟まります。ObjectBox はオブジェクトを直接読み書きするため、この変換のオーバーヘッドが少なく、素直で速い構成にしやすいです。ゲームのデイリー記録のように「頻繁に読み書きする小さなオブジェクト」を扱うログ簿の用途とも相性がよく、体感でも軽快でした。

※ 速度は使い方・データ量・端末に依存します。ここでの「軽量・高速」は、あくまで ORM のマッピング層を挟まない構造上の特性という意味合いです。厳密な比較は、実際のデータで計測するのが確実です。

理由3: SQLite と同じ感覚で使える(学習コストが低い)

「専用のオブジェクトDB」と聞くと身構えますが、実際は SQLite を使うときと同じ感覚で扱えます。

  • 端末内で完結する組み込みDBであること(サーバ不要)は SQLite と同じ。
  • エンティティ(保存する型)にアノテーションを付け、コード生成でストア操作のコードを用意する、という流れ。
  • 「保存する・IDで引く・条件で絞る・並べ替える」といった基本操作の考え方は、SQL に慣れていればすぐ馴染む。

Flutter 向けには objectbox / objectbox_flutter_libs / objectbox_generator が揃っていて、エンティティ定義から必要なコードを生成できます。SQLite 系から乗り換えても学習コストが低く、移行の心理的ハードルが小さかったのも大きいです。

注意点: スキーマの UID を保持する

いいことばかりではなく、ObjectBox ならではの注意もあります。ObjectBox はエンティティやプロパティを内部的に UID で管理していて、この対応情報が objectbox-model.json に記録されます。

この UID を安易に変更・削除すると、既存データとの対応が取れなくなり移行不能になります。 スキーマを変更するときは UID を保持する——ここは SQLite のマイグレーションとは勝手が違うので、最初に押さえておくべきポイントでした。

まとめ

ログ簿が ObjectBox を選んだ理由は、

  1. ネイティブAndroid時代から使っていたので、資産と地続きに移行できる
  2. オブジェクトを直接保存でき、ORM のマッピング層を挟まないぶん軽量・高速に扱える
  3. SQLite と同じ感覚で使えて学習コストが低い

の3点でした。「速いDB」だから選んだというより、移行の連続性と扱いやすさが、ログ簿の状況に一番合っていたという技術選定です。新規プロジェクトなら drift など SQLite 系も有力なので、最後は「既存資産」と「チームの慣れ」で決めるのが現実的だと思います。