Realmは、iOSとAndroid向けにSQLiteやCore Dataの代替として開発されたモバイルオブジェクト指向NoSQLデータベースです。データはメモリ内のオブジェクトに直接アクセスできる独自形式で保存され、高い読み取り・書き込み速度を実現します。リアクティブ通知、Realm Syncによる自動同期、クロスプラットフォームデータモデルにより、Realmは10億台以上のデバイスで使用されています(MongoDBデータ、2025年)。
主要ポイント
Realmは、モバイルアプリケーション専用に作られたオブジェクト指向データベースです。SQLiteとは異なり、RealmはSQLやリレーショナルモデルを使用しません。データはライブオブジェクト(Live Objects)として保存され、中間ORM層なしで直接アクセスできます。開発者は通常の言語オブジェクト(Swift、Kotlin、Dart)を操作するだけで、自動的にデータベースに保存されます。
Realmは2014年にスタートアップRealm Inc.として登場し、2019年にMongoDB Inc.に買収されました。それ以来、RealmはMongoDB Realmとして開発されています。これはモバイルデータ同期のための統合プラットフォームAtlas Device Syncの一部です。基本のローカルRealmデータベースは無料でオープンソース(Apache 2.0ライセンス)のままですが、Realm Sync(クラウド同期)はサブスクリプションで提供されます。
MongoDB Developer Report(2025年)によると、Realmは主要なローカルストレージとしてモバイルアプリケーションの15%で使用されています。主なユースケースは、オフラインモードのアプリケーション、複雑なオブジェクトモデル、デバイス間の同期が必要なアプリケーションで、Realmは開発速度とオブジェクト操作の容易さでSQLiteを上回ります。
Live Objects — 各Realmオブジェクトはメモリマップドファイルを介してディスクにリンクされています。任意のスレッドでオブジェクトを変更すると、手動通知なしですべての他のスレッドに即座に反映されます。Realm通知を介してデータが変更されると、UIは自動的に再描画されます。Zero-copy — Realmはデータベースからオブジェクトにデータをコピーしません。オブジェクト自体がメモリ内のデータです。
RealmコアはC++で書かれており、データインデックスにB+ツリーを使用します。各行がリレーショナルテーブルのレコードであるSQLiteとは異なり、Realmはオブジェクトをグラフ構造のノードとして保存し、オブジェクト間の直接参照(前方ポインタ)を持ちます。オブジェクト間の関係は外部キーではなく直接ポインタであり、JOIN操作の必要性を排除します。
Realmファイル(.realm拡張子)はメモリマップドされています。OS自体がアクセスに応じてファイルページのメモリへのロードを管理します。これにより、Realmは利用可能なRAMより大きなデータベースを扱うことができ、RAMに収まるデータに対してはネイティブ言語データ構造(Swift ArrayやKotlin List)レベルの読み取りレイテンシを提供します。
メモリマップドファイル — Realmの主要技術です。データベースファイルから言語オブジェクトにデータをコピーする代わりに(SQLiteがsqlite3_step + sqlite3_column_*で行うように)、Realmはデータベースファイルをプロセスのアドレス空間に直接マッピングします。言語オブジェクトはマップされたメモリ内のデータへの単なるポインタです。オブジェクトを変更すると、個別のsave呼び出しなしでディスク上のデータベースが変更されます。
| 特性 | Realm(zero-copy) | SQLite(コピー) |
|---|---|---|
| 読み取り | メモリ直接アクセス(ナノ秒) | オブジェクトにコピー(マイクロ秒) |
| 書き込み | メモリマップドファイルへの即時書き込み | SQL INSERT/UPDATEトランザクションのsave() |
| 関係 | 直接ポインタ(前方ポインタ) | 外部キー + JOIN |
| メモリ消費 | ファイル + OSページキャッシュ | オブジェクト + SQLiteページキャッシュ |
| ライブオブジェクト | あり(自動更新) | なし(新しいfetchが必要) |
メモリ消費は、アクティブな読み取り中はRealmの方が高くなります(ファイル全体または大部分がメモリにマップされます)が、書き込み操作中はオブジェクトコピーのメモリ割り当てが不要なため低くなります。モバイルデバイスで最大1GBのデータベースの場合、メモリマップドアプローチは中間コピーを行うSQLiteよりも全体的なパフォーマンスが優れています。
SQLiteはSQLとACIDトランザクションを備えたリレーショナルDBMSです。Realmはメモリマップドアクセスを備えたオブジェクトNoSQLデータベースです。Core DataはSQLite上のAppleのORM層です。3つのアプローチにはそれぞれ適用分野と強みがあります。Realmは直接オブジェクトアクセス速度とリアクティビティに優れ、SQLiteは汎用性と成熟度、Core DataはAppleエコシステムとの統合に優れています。
Realmの読み取りパフォーマンスは、zero-copyアクセスによりSQLiteより10〜50%高くなっています。RealmはSQL解析が不要でメモリマップドページを直接変更するため、書き込みも高速です。ただし、Realmは大規模データベース(500MB超)を扱う場合、ファイルがアドレス空間に完全にマップされるため、より多くのRAMを消費する可能性があります。
| 基準 | Realm | SQLite | Core Data |
|---|---|---|---|
| タイプ | NoSQLオブジェクトDB | リレーショナルDBMS(SQL) | SQLite上のORM |
| 読み取り速度 | 高速(zero-copy) | 中程度 | 中程度(ORMオーバーヘッド) |
| リアクティビティ | Live Objects(組み込み) | ラッパーが必要(Room/GRDB) | NSFetchedResultsController |
| 同期 | Realm Sync(MongoDB Atlas) | カスタム実装が必要 | NSPersistentCloudKitContainer |
| プラットフォーム | iOS、Android、Flutter、RN、Node.js | iOS、Android、Web、デスクトップ | iOS/macOSのみ |
| ライブラリサイズ | 約4MB | 約600KB | SDKに組み込み |
RealmとSQLiteの選択は、多くの場合、優先順位に帰着します。開発速度とリアクティビティ(Realm)か、制御と汎用性(SQLite)か。Realmはデータモデルが頻繁に変更され、ライブUI更新を迅速に取得することが重要なMVPやプロトタイプに特に適しています。SQLite/Roomはデータ量が多く複雑な分析クエリを必要とする成熟した製品に適しています。
Realm Kotlin SDKはAndroid向けの公式ライブラリで、Kotlinで書かれています(Java SDKのラッパーではありません)。データモデルはRealmObjectを継承するクラスで定義され、一意の識別子には@PrimaryKeyアノテーションを使用します。Realm KotlinはKotlin Coroutines、Flow、およびコンパイル時コード生成のためのKSP(Kotlin Symbol Processing)をサポートしています。
RealmQueryはSQLなしでフィルタリングするための型安全なAPIを提供します。クエリはメソッドチェーンで構築します:query → filter → sort → find。結果はリスト(メモリにロード)またはFlow(データ変更時に更新されるリアクティブストリーム)として返せます。Realm Kotlinはネストされたオブジェクトとリスト(RealmList)もサポートしています。
データモデルRealmはRealmObjectインターフェースを実装するデータクラスとして定義されます。_idフィールドは一意の識別のために@PrimaryKeyでマークされます。1対多の関係はRealmList(他のRealmObjectのリスト)を介して実装されます。すべての書き込み操作(作成、更新、削除)はwriteトランザクションブロック内で実行されます。
class Project : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var name: String = ""
var tasks: RealmList<Task> = realmListOf()
}
class Task : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var title: String = ""
var isComplete: Boolean = false
}
val config = Realm.Configuration.Builder(
schema = setOf(Project::class, Task::class)
).build()
val realm = Realm.open(config)
realm.write { transactionRealm ->
val project = copyToRealm(Project().apply {
name = "Mobile App"
})
project.tasks.add(copyToRealm(Task().apply {
title = "Design UI"
}))
}
val projects: Flow<RealmResults<Project>> =
realm.query<Project>()
.sort(Project::name, Sort.ASCENDING)
.asFlow()
Flowを返すクエリは、ProjectまたはTaskの追加、更新、削除など、Realm内のデータ変更時に自動的に新しい結果を発行します。FlowアプローチはComposeと完璧に調和します。ViewModelのcollectAsState()は、リストアダプターを手動で更新したりLiveDataを使用したりせずに、データ変更時に自動的にUIを再構成します。
Realm Swift SDKは、async/await、Combine Publishers、Swift ConcurrencyをサポートするネイティブSwift APIを提供します。データモデルはObjectを継承するクラスとして定義され、プロパティには@Persistedを使用します。Realm Swiftは変更時に自動的にオブジェクトを更新し、通知(NotificationToken)を使用して個々のオブジェクトやコレクションの変更を購読できます。
@ObservedRealmObjectと@ObservedResultsは、Realmデータが変更されたときに自動的にViewを再描画するSwiftUI用のProperty Wrapperです。@ObservedResultsはクエリ結果で動作し、@ObservedRealmObjectは特定のオブジェクトで動作します。両方のプロパティはViewの初期化解除時に購読をキャンセルします。
SwiftUI統合はRealm SDKの強みの1つです。@ObservedResults Property WrapperはRealmクエリをSwiftUIの表示に結び付けます。タスクが変更されると、SwiftUIは自動的にリストを再構成します。realm.writeAsyncはUIをブロックせずにバックグラウンドスレッドでトランザクションを実行します。
import RealmSwift
class TaskItem: Object, Identifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var title: String = ""
@Persisted var isDone: Bool = false
@Persisted var priority: Int = 0
}
struct TaskListView: View {
@ObservedResults(TaskItem.self,
sortDescriptor: SortDescriptor(["priority"]))
var tasks
var body: some View {
List {
ForEach(tasks) { task in
TaskRow(task: task)
}
}
Button("Add Task") {
let realm = try! Realm()
try! realm.write {
realm.add(TaskItem(value: ["title": "New task"]))
}
}
}
}
@ObservedResultsはRealmクエリのライフサイクルを自動的に管理します。View作成時に変更の購読が作成され、破棄時にキャンセルされます。Property Wrapperはオプションの述語(NSPredicate)とソート記述子を受け入れます。これにより、手動でフェッチリクエストを記述したり、ViewModelを作成したり、Realm通知を購読したりする必要がなくなります。
オフラインアプリケーション — Realmはインターネットなしでデータを利用可能にしなければならないシナリオに最適です。組み込み同期(MongoDB AtlasとのRealm Sync)はネットワーク接続時に自動的に競合を解決します。アプリはローカルデータで動作を続け、バックグラウンド同期は接続が利用可能になるとデータを更新します。
リアクティブインターフェース — Live ObjectsとFlow/Combine通知により、Realmは頻繁に更新されるデータを扱うアプリケーション(チャット、タスクフィード、共同ドキュメント)に便利な選択肢となります。手動でreloadDataやinvalidateを呼び出さなくても、データの追加、変更、削除時にUIが自動的に更新されます。
クロスプラットフォームプロジェクト — RealmはKotlin Multiplatform(KMP)、Flutter、React Native、Xamarinをサポートしています。データモデルは一度定義され、すべてのプラットフォームで使用されます。これによりコードの重複が減り、共通のビジネスロジックを持つiOSとAndroidアプリケーション間でスキーマの一貫性が保証されます。
Realm SyncはMongoDB Atlasに組み込まれたクラウドサービスです。アプリケーションはユーザーのデバイスとサーバー間でデータを自動的に同期します。競合は"last write wins"戦略またはサーバー上のカスタムConflict Resolution Functionsを使用して解決されます。Realm Syncはトラフィックを削減するための部分同期(データのサブセット)をサポートしています。
class SyncRepository {
private val app = App(
AppConfiguration(
appId = "my-realm-app-id"
)
)
suspend fun syncData() {
val user = app.login(Credentials.anonymous())
val config = SyncConfiguration.Builder(
user, setOf(Project::class)
).build()
val syncedRealm = Realm.open(config)
// 自動同期がアクティブです
}
}
SyncConfigurationはMongoDB Atlasへの接続を構成し、同期するモデルのセットを定義します。ユーザー認証後、Realmは自動的にクラウドからデータをロードし、ローカルの変更とマージします。同期はバックグラウンドスレッドで実行され、手動呼び出しは不要です。SyncConfigurationを使用してRealmインスタンスを作成するだけです。
よくある質問
はい、ローカルのRealmデータベースは完全に無料です(Apache 2.0ライセンス)。MongoDB Atlas経由のRealm Sync(クラウド同期)はAtlas Device Syncサブスクリプションに含まれる有料サービスです。無料のAtlasティアには、最初の500MBのデータと月間100万回の操作が含まれます。
はい、移行はSQLiteからJSONにデータをエクスポートし、最初のアプリロード時にRealmにインポートすることで可能です。大量のデータの場合は、ストリーミング移行を使用してください。ユーザーが新しいアプリバージョンに移行する間、両方のデータベースに並行してデータを書き込み、その後SQLiteファイルを削除します。
Realm Syncはデフォルトで"last write wins"戦略を使用します。最後の書き込みが前の書き込みを上書きします。複雑な競合の場合は、アプリケーションのビジネスロジックに従って異なるデバイスからの変更をマージするカスタムConflict Resolution FunctionsをMongoDB Atlasサーバーに設定します(例えば、置き換えではなく値のマージ)。
RealmはデータベースレベルでSQL集計(SUM、AVG、GROUP BY)をサポートしていません。分析クエリの場合は、Realm Syncを介してRealmからMongoDB Atlasにデータをエクスポートし、MongoDB Aggregation Pipelineを通じて集計を実行することをお勧めします。単純なカウントの場合は、realm.query<T>().count()を使用してください。
Realmはデフォルトでデータを暗号化しません。暗号化するには、設定で64バイトの鍵を指定します:Realm.Configuration(encryptionKey: key)。暗号化はAES-256 + SHA-2 HMACを使用し、操作のオーバーヘッドが10〜20%増加します。暗号化なしでは、.realmファイルはファイルシステムにアクセスできる任意のプロセスで読み取ることができます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。