LASSIC Media らしくメディア

2026.07.03 らしくコラム

モバイルアプリのローカルDB実装と選び方

LASSIC IT事業部|元請(プライムベンダー)としてシステム保守・運用を受託

モバイルアプリのローカルDB実装のイメージ

この記事のポイント

  • ローカルDBの実装は、端末内にSQLiteベースのデータ永続化の仕組みを構築する工程で、OS・言語・アプリ要件によって選ぶべき手段が変わります。
  • iOSはCore DataまたはSwiftData、AndroidはRoom、クロスプラットフォームではRealm等が代表的な選択肢で、それぞれ設計思想が異なります。
  • スキーマ設計・マイグレーション・暗号化を初期段階で軽視すると、後工程での改修コストが膨らみやすくなります。

ローカルDBとは — 端末内にデータを永続化する仕組み

スキーマ設計・データ永続化のイメージ

モバイルアプリのローカルDBとは、スマートフォンやタブレットの端末内にデータを保存し、アプリを終了しても情報を保持し続ける仕組みを指します。多くの実装は米SQLiteが提供する組み込み型のリレーショナルデータベースエンジンを基盤にしており*1、その上にOS・言語ごとの永続化フレームワークが載る構成が一般的です。

図

モバイルアプリのローカルDB実装における5ステップ

ローカルDBが必要になる場面は幅広いです。ログイン情報やユーザー設定の保持、オフライン時にも閲覧できるコンテンツのキャッシュ、入力途中のフォームデータの一時保存などが代表例に挙げられます。通信環境に依存せずアプリの基本機能を動かせる点が、サーバー側DBだけに頼る設計との違いです。

注意したいのは、ローカルDBの実装選定と、複数端末・サーバー間でデータを一致させる同期設計は別の論点であることです。同期設計(通信断時の競合解決やプッシュ/プル方式の設計)は別稿で扱っており、本稿は端末内にどうデータを保存し、どの技術で永続化層を組むかという実装選定に絞って解説します。

SQLiteは軽量なファイルベースのエンジンで、サーバーやデーモンなしにアプリのプロセス内で完結して動作する設計です*1。この特性から、組み込みデバイスやモバイルアプリのようにインストール・管理者不要で動作させたい用途に向いています*1。一方で複数クライアントがネットワーク経由で同じデータベースに同時アクセスする用途や、書き込みが集中する高トラフィックな用途にはSQLite単体は適さないとされています*1。モバイル端末内という閉じた実行環境での永続化に向いた技術だと理解しておくと、選定の前提が整理しやすくなります。

SQLite・Room・Core Data・SwiftData・Realmの違い

ローカルDBの実装方式は、OSと開発言語によって主要な選択肢が分かれます。まずAndroidとiOSそれぞれの標準的な選択肢を押さえ、次にクロスプラットフォームで使われる第三の選択肢を確認します。

Androidの標準はRoom — SQLite APIの直接利用は非推奨

Android公式ドキュメントは、SQLite APIを直接使用するのではなくRoomパーシステンスライブラリの使用を推奨しています*2。RoomはSQLite上の抽象化レイヤーで、コンパイル時のSQLクエリ検証、定型的なコードの削減、マイグレーションパスの整備といった利点を提供します*2。エンティティ(テーブルに対応するデータクラス)・DAO(データアクセスを担うインターフェース)・データベースクラスの3要素で構成する設計が基本です*2

SQLite APIを素の状態で扱うと、SQL文字列の組み立てミスが実行時まで発覚しない、マイグレーション処理を手動で書く必要があるといった負担が生じます。Roomはこれらをコンパイル時検証と自動生成コードで軽減する位置づけのライブラリです。

iOSはCore DataとSwiftDataの2系統が併存

iOS向けの永続化フレームワークとしては、長年使われてきたCore Dataと、比較的新しいSwiftDataの2系統が存在します。Core Dataはオブジェクトグラフの管理とデータ永続化を担うフレームワークで、SQLite・バイナリ・インメモリなど複数の永続化ストア形式に対応する設計です。SwiftDataはSwift言語に最適化された宣言的なAPIを持つ新しい永続化フレームワークで、内部的にCore Dataの仕組みを踏襲しつつ、より簡潔な記述で扱える点が特徴とされています。

新規プロジェクトでどちらを選ぶかは、対応する最低OSバージョンの要件に左右されます。SwiftDataは比較的新しいOSバージョン以降を対象とした機能のため、旧バージョンのサポートが必要な案件ではCore Dataが選択肢になりやすいのが実情です。既存アプリの改修であれば、すでに構築済みのCore Data資産をどこまで引き継ぐかという判断も必要になります。

クロスプラットフォームの選択肢としてのRealm

Flutter・React Native等でiOS/Androidを1つのコードベースで開発する場合や、オブジェクト指向のデータモデルをそのまま扱いたい場合には、Realm(MongoDBが提供するモバイル向けデータベース)が選択肢に入ります。RealmはSQLiteとは異なる仕組みのストレージエンジンを持つオブジェクトデータベースで、暗号化オプションやリアルタイム同期機能を備える製品として提供されている点が特徴です。ただしOS標準のフレームワークではないため、ライブラリの継続的なアップデート方針や、将来のOSバージョンアップへの追随状況を確認したうえで採用を判断する必要があります。

3つの系統に共通するのは、「素のSQLiteを直接扱う」設計ではなく、「抽象化レイヤーを介して構造化された形でデータを操作する」設計思想へと業界標準が収れんしている点です。技術選定の軸はエンジンそのものの優劣ではなく、OS・言語・チームのスキルセットとの適合性に置くべきだと分かります。

技術 対象OS・環境 設計の特徴
Room Android SQLite上の抽象化レイヤー。
コンパイル時にSQLクエリを検証できます。
Core Data iOS/macOS(旧来からの標準) オブジェクトグラフ管理を担うフレームワーク。
SQLite・バイナリ等複数の永続化ストアに対応します。
SwiftData iOS/macOS(比較的新しいOS世代以降) Swift言語に最適化された宣言的API。
内部的にCore Dataの仕組みを踏まえています。
Realm iOS/Android/クロスプラットフォーム SQLiteと異なる仕組みのオブジェクトDB。
暗号化・同期機能を製品として提供します。

スキーマ設計とマイグレーションの勘所

ローカルDBの実装で見落とされやすいのが、リリース後にスキーマ(データ構造の定義)を変更する場面への備えです。アプリは一度ストアで公開すると、旧バージョンを使い続けるユーザーが一定期間残るため、後方互換性を保った移行手順が欠かせません。

Roomのマイグレーションはバージョン番号で管理する

Room公式ドキュメントは、事前にデータを投入したデータベースファイルを使う「Prepopulate」機能について、通常のマイグレーション実装がある場合はそちらが優先され、データが保持されると説明しています*3。逆に、正式なマイグレーション処理を書かずにバージョン番号だけを上げると、Roomは既存のテーブルを削除して新しいスキーマで再作成する破壊的マイグレーションの経路をたどります*3。この挙動を理解せずに実装すると、アップデート後に既存ユーザーのデータが失われる不具合につながりかねません。

Core Data/SwiftDataは軽量マイグレーションと手動マイグレーションを使い分ける

Core Dataには、カラム追加のような単純なスキーマ変更を自動で処理する軽量マイグレーションの仕組みがあります。一方、データ型の変更やエンティティの分割・統合など複雑な変更では、変換ロジックを自前で記述する手動マイグレーションが必要になります。SwiftDataも同様に、単純な変更は自動処理される一方、複雑な変更には明示的なスキーマ移行の定義が求められる設計です。どちらを使うにせよ、リリース前にどのレベルの変更まで自動対応できるかを見極めておく必要があります。

マイグレーションのテストを本番相当データで行う

スキーマ変更のテストを空のデータベースだけで行うと、実データ特有の不整合(NULL値の扱い、文字数超過、重複キーなど)を見逃しやすくなります。旧バージョンのアプリで生成された実データに近いテストデータを用意し、マイグレーション処理を通してから結果を検証する工程を、リリース前のチェックリストに組み込むことが望ましいでしょう。

マイグレーション設計を誤ると、アプリのアップデート直後に起動クラッシュやデータ消失が発生し、ストアのレビュー評価が急落する事態を招きます。一度失った評価を取り戻すには相応の期間を要するため、初期のスキーマ設計段階で将来の変更を見越した余白を持たせておく判断が有効です。

端末内データの暗号化と情報漏えい対策

ローカルDBに保存したデータは、端末の紛失・盗難時に第三者からアクセスされるリスクを抱えます。個人情報や認証トークンを扱うアプリでは、保存データの暗号化を設計段階から検討する必要があります。

SQLiteの暗号化は拡張機能かOS標準機能で対応する

SQLite本体の公式ドキュメントは、不正な入力や信頼できないデータベースファイルへの対策として、実行できるSQL操作を制限する仕組みや整合性検証の手段を挙げていますが*4、標準機能としてのファイル全体の暗号化には言及していません*4。暗号化が必要な場合は、SQLite Encryption Extension(SEE)のような拡張機能を組み込むか、OSが提供するファイルシステムレベルの暗号化・Keychain(iOSの認証情報管理機構)やAndroid Keystoreのような鍵管理の仕組みと組み合わせる設計が一般的です。

Room/Core Data/SwiftDataは暗号化を標準搭載しない前提で設計する

Room・Core Data・SwiftDataはいずれも、データベースファイル自体の暗号化を標準機能として搭載しているわけではありません。暗号化が必要な要件では、SQLCipherのような暗号化ライブラリの導入や、OS標準の鍵管理機構と連携した設計を別途組み込む前提で計画を立てる必要があるでしょう。この点を要件定義の段階で確認せずに開発を進めると、リリース直前になって暗号化要件が発覚し、スキーマの作り直しが発生する事態になりかねません。

認証トークン・個人情報は保存場所を分ける判断も有効

アプリ内のすべてのデータを一律にDBへ保存するのではなく、認証トークンのような機微情報はOSが提供する専用の保管領域(Keychain・Keystore)に分離し、一般的なアプリデータのみをローカルDBに保存する設計も選択肢に入ります。保存場所を分けることで、DB全体を暗号化する負荷をかけずに、機微情報だけを保護レベルの高い領域で管理できます。

パフォーマンスを左右するクエリ設計とインデックス

端末内データの暗号化のイメージ

ローカルDBの実装が完了した後も、データ量の増加に伴って動作が重くなる問題が起こり得ます。設計段階でクエリの発行方法とインデックスの設計を意識しておくと、後工程での手戻りを抑えられます。

N+1クエリ問題を避ける

一覧画面で関連データを表示する際、1件ごとに追加クエリを発行する実装(N+1クエリ問題と呼ばれる非効率なパターン)は、件数が増えるほど処理時間が線形以上に悪化します。Room・Core Data・SwiftDataのいずれも、関連データを一括で取得するクエリ・フェッチの仕組みを備えているため、一覧表示のような頻出画面では一括取得の設計を優先する必要があります。

頻繁に検索・ソートする列にインデックスを張る

日付や状態フラグなど、一覧画面の絞り込みやソートで頻繁に使う列には、インデックス(検索を高速化するための補助的なデータ構造)を設定する設計が有効です。インデックスを増やしすぎると書き込み時の負荷が増すため、実際の検索パターンに基づいて必要な列を絞り込む判断が求められます。

大量データの一括処理はトランザクションでまとめる

数百件・数千件単位のデータを一括で挿入・更新する処理を1件ずつ個別のトランザクションで実行すると、ディスクへの書き込み回数が増え、処理時間が長くなります。複数の変更を1つのトランザクションにまとめて実行する設計に変えるだけで、体感速度が明確に速くなる場合があります。この最適化はRoom・Core Data・SwiftDataのいずれでも標準的にサポートされている手法です。

パフォーマンス検証は実機、それも低スペック帯の端末で行う点が重要です。開発機として使う高性能端末だけで検証すると、実際のユーザー層が使う端末での体感速度の劣化に気づけないまま公開してしまうリスクがあります。

外注時に確認すべき技術選定と引き継ぎの論点

ローカルDBの実装をアプリ開発会社に外注する場合、技術選定を任せきりにすると、後になって自社の要件と合わない設計だったと気づく事態が起こり得ます。発注前に確認しておきたい論点を整理します。

自社で内製するには何が必要か

ローカルDBの実装を内製で行うには、iOSとAndroidそれぞれのプラットフォーム知識に加え、スキーマ設計・マイグレーション設計・暗号化要件の整理という3つの専門領域を担える人材が必要です。特にマイグレーション設計は、リリース後の複数バージョンを想定した設計判断が求められるため、単発の実装経験だけでは対応が難しい領域です。社内にモバイルアプリの永続化層を専門に扱うエンジニアがいない場合、要件定義の段階でつまずくケースが少なくありません。

発注先が選定した技術の根拠を確認する

提案書に「Room・Core Data・SwiftDataを採用します」とだけ書かれている場合、なぜその技術を選んだのかという根拠まで確認する必要があります。対応OSバージョンの下限、将来的な保守体制、暗号化要件への対応方法、マイグレーション方針を発注前の打ち合わせで具体的に質問し、回答の解像度を見ることが技術力を見極める手がかりになります。

ソースコードとスキーマ定義の引き継ぎ範囲を契約に明記する

開発会社との契約が終了した後、別の会社に保守を引き継ぐ可能性がある場合は、スキーマ定義書・マイグレーション履歴・DAO層のソースコードを納品物に含めるよう契約段階で明記しておく必要があります。これらの資料がないまま引き継ぐと、後任の開発会社が既存のDB構造を解析するところから作業を始めることになり、追加の調査コストが発生しかねません。

技術選定そのものを丸投げにせず、自社側が最低限の論点を把握したうえで発注先と対話する体制を整えることが、外注を成功させる実務上のポイントです。

まとめ:ローカルDB選定を機能させる3つの判断軸

本稿では、モバイルアプリのローカルDB実装における技術選定とスキーマ設計・暗号化・パフォーマンスの勘所を整理しました。要点を3つに集約すると次の通りです。第一に、ローカルDBの選択肢はOS・言語によって定まり、SQLite APIを直接扱うのではなく、Room・Core Data・SwiftDataといった抽象化レイヤーを介する設計が業界標準になっていることです。第二に、スキーマ設計とマイグレーション、暗号化の要件は初期段階で確認しないと、リリース後の手戻りにつながりやすいという点が挙げられます。第三に、外注する場合も技術選定の根拠と引き継ぎ資料の範囲を発注前に確認する姿勢が、長期的な保守性を左右します。

LASSICに相談するメリット

LASSICは元請としてモバイルアプリの受託開発・運用保守を担う立場から、iOS/Androidのローカルデータ永続化層の設計を含めた技術選定支援が可能です。スキーマ設計・マイグレーション方針・暗号化要件の整理まで、貴社の要件に合わせて相談を承ります。まずはお気軽にご相談ください。

よくある質問

SQLiteを直接使う実装とRoom・Core Dataを使う実装は何が違いますか。

SQLite APIを直接扱うと、SQL文字列の記述ミスが実行時まで発覚しないほか、マイグレーション処理を手動で実装する負担が生じます。Room・Core Dataはこれらを抽象化レイヤーとして吸収し、コンパイル時の検証や定型処理の自動化を提供する仕組みです*2。Android公式もSQLite APIの直接利用ではなくRoomの使用を推奨しています*2

iOSアプリの新規開発ではCore DataとSwiftDataのどちらを選ぶべきですか。

対応する最低OSバージョンの要件で判断が変わります。SwiftDataは比較的新しいOS世代以降を対象とした機能のため、旧バージョンの端末をサポート対象に含める場合はCore Dataが選択肢になります。既存アプリの改修であれば、すでに構築済みのCore Data資産をどこまで引き継ぐかという観点も判断材料になるでしょう。

ローカルDBのマイグレーションでデータが消えるのはなぜですか。

正式なマイグレーション処理を実装せずにスキーマのバージョン番号だけを上げると、既存のテーブルを削除して新しいスキーマで再作成する破壊的な処理が実行される場合があるためです*3。Room公式ドキュメントも、通常のマイグレーション実装があればデータが保持される一方、実装がない場合は再作成の経路をたどると説明しています*3。リリース前に本番相当データでマイグレーションを検証する工程が欠かせません。

ローカルDBの中身は暗号化しなくても問題ありませんか。

個人情報や認証情報を扱うアプリでは、端末の紛失・盗難時のリスクを踏まえて暗号化の検討が必要です。Room・Core Data・SwiftDataは暗号化を標準搭載していないため、SQLCipherのような拡張ライブラリの導入や、OS標準の鍵管理機構と組み合わせる設計を別途計画する必要があります。

ローカルDBの実装と端末間の同期機能は同じ発注範囲で依頼できますか。

技術としては連続していますが、論点は別です。ローカルDBの実装選定は端末内でのデータ永続化の設計であるのに対し、同期機能は複数端末・サーバー間でのデータ一致や通信断時の競合解決を扱う設計です。発注時にはどちらの工程まで含めるかを要件定義の段階で明確に切り分けておくと、見積もりの範囲を把握しやすくなります。

著者:テレリモ総研編集部 鈴木 亮佑


ITアウトソーシング・システム開発のご相談はLASSICへ

元請(プライムベンダー)として、貴社の課題に合わせた体制構築・開発支援をご提案します。まずはお気軽にご相談ください。

無料相談はこちら

ご不明な点はお問い合わせフォームからもご連絡いただけます。

  1. *1 出典:SQLite Consortium「Appropriate Uses For SQLite」https://www.sqlite.org/whentouse.html
  2. *2 出典:Google「Save data in a local database using Room」(Android Developers)https://developer.android.com/training/data-storage/room
  3. *3 出典:Google「Prepopulate your Room database」(Android Developers)https://developer.android.com/training/data-storage/room/prepopulate
  4. *4 出典:SQLite Consortium「Defense Against The Dark Arts」https://www.sqlite.org/security.html


View