Realm у мобільних додатках: що це таке і як працює

Автор: IT Sectr Опубліковано: 2026-03-12 Час читання: 11 хв

Realm — мобільна об'єктно-орієнтована NoSQL база даних, розроблена як альтернатива SQLite та Core Data для iOS та Android. Дані зберігаються у власному форматі з прямим доступом до об'єктів у пам'яті, що забезпечує високу швидкість читання та запису. Завдяки реактивним сповіщенням, автоматичній синхронізації через Realm Sync та кросплатформній моделі даних, Realm використовується більш ніж на 1 мільярді пристроїв (дані MongoDB, 2025).

Головне

  • Realm — NoSQL об'єктна БД для мобільних платформ з прямим доступом до даних в оперативній пам'яті.
  • Live Objects — об'єкти Realm автоматично оновлюються при зміні даних без ручного перезавантаження.
  • Zero-copy — дані не копіюються між шарами додатку, що усуває накладні витрати ORM.
  • Realm Sync — вбудована синхронізація між пристроями через MongoDB Atlas Device Sync.
  • Кросплатформність — модель даних визначається один раз для iOS, Android, Flutter та React Native.

Що таке Realm?

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 за швидкістю розробки та зручністю роботи з об'єктами.

Принципи Realm

Live Objects — кожен об'єкт Realm пов'язаний з диском через відображення в пам'ять (memory-mapped file). Зміна об'єкта в будь-якому потоці негайно відображається у всіх інших потоках без ручного сповіщення. Інтерфейс UI автоматично перемальовується при зміні даних через Realm-сповіщення. Zero-copy — Realm не копіює дані з БД в об'єкти; об'єкти — це і є дані в пам'яті.

Як влаштована Realm: архітектура та зберігання

Ядро Realm написано на C++ і використовує B+ Tree для індексації даних. На відміну від SQLite, де кожен рядок — це запис у реляційній таблиці, Realm зберігає об'єкти як вузли в графовій структурі з прямими посиланнями між ними (forward pointers). Зв'язки між об'єктами — це не foreign keys, а прямі покажчики, що усуває необхідність в JOIN-операціях.

Файли Realm (розширення .realm) є memory-mapped — ОС сама керує завантаженням сторінок файлу в пам'ять у міру звернення. Це дозволяє Realm працювати з базами, що перевищують доступну оперативну пам'ять, і забезпечує read latency на рівні нативних структур даних мови (Swift Array або Kotlin List) для даних, що вміщуються в RAM.

Zero-copy та Live Objects

Memory-mapped файли — ключова технологія Realm. Замість того щоб копіювати дані з файлу БД в об'єкти мови (як робить SQLite через sqlite3_step + sqlite3_column_*), Realm відображає файл бази прямо в адресний простір процесу. Об'єкти мови — це просто покажчики на дані у відображеній пам'яті. Зміна об'єкта змінює базу на диску без окремого save-виклику.

ХарактеристикаRealm (zero-copy)SQLite (копіювання)
ЧитанняПрямий доступ до пам'яті (наносекунди)Копіювання в об'єкт (мікросекунди)
ЗаписНегайний запис у memory-mapped filesave() з транзакцією SQL INSERT/UPDATE
Зв'язкиПрямі покажчики (forward pointers)Foreign key + JOIN
Споживання пам'ятіФайл + кеш сторінок ОСОб'єкти + кеш сторінок SQLite
Живі об'єктиТак (автоматичне оновлення)Ні (потрібен новий fetch)

Споживання пам'яті Realm вище при активному читанні (весь файл або його велика частина відображена в пам'ять), але нижче при операціях запису, оскільки не потрібне виділення пам'яті під копії об'єктів. Для баз розміром до 1 ГБ на мобільних пристроях memory-mapped підхід дає кращу загальну продуктивність, ніж SQLite з його проміжним копіюванням.

Realm vs SQLite vs Core Data: порівняння

SQLite — реляційна СУБД з SQL та ACID-транзакціями. Realm — об'єктна NoSQL БД з memory-mapped доступом. Core Data — ORM-шар Apple поверх SQLite. Кожен із трьох підходів має свою область застосування та сильні сторони. Realm виграє у швидкості прямого доступу до об'єктів та реактивності, SQLite — в універсальності та зрілості, Core Data — в інтеграції з Apple-екосистемою.

Продуктивність Realm на операціях читання на 10-50% вища за SQLite завдяки zero-copy доступу. На операціях запису Realm також швидший за рахунок відсутності SQL-синтаксичного аналізу та прямого змінення memory-mapped сторінок. Однак Realm може споживати більше оперативної пам'яті при роботі з великими базами (>500 МБ), оскільки файл повністю відображається в адресний простір.

КритерійRealmSQLiteCore Data
ТипNoSQL об'єктна БДРеляційна СУБД (SQL)ORM поверх SQLite
Швидкість читанняВисока (zero-copy)СередняСередня (ORM overhead)
РеактивністьLive Objects (вбудовано)Потрібна обгортка (Room/GRDB)NSFetchedResultsController
СинхронізаціяRealm Sync (MongoDB Atlas)Потрібна кастомна реалізаціяNSPersistentCloudKitContainer
ПлатформиiOS, Android, Flutter, RN, Node.jsiOS, Android, Web, DesktopТільки iOS/macOS
Розмір бібліотеки~4 МБ~600 КБВбудовано в SDK

Вибір між Realm та SQLite часто зводиться до пріоритетів: швидкість розробки та реактивність (Realm) проти контролю та універсальності (SQLite). Realm особливо хороший для MVP та прототипів, де модель даних змінюється часто і важливо швидко отримувати живі оновлення UI. SQLite/Room кращий для зрілих продуктів з великими обсягами даних та складними аналітичними запитами.

Realm на Android: Kotlin SDK

Realm Kotlin SDK — офіційна бібліотека для Android, написана на Kotlin (не обгортка над Java SDK). Модель даних визначається через класи, успадковані від RealmObject, з анотацією @PrimaryKey для унікального ідентифікатора. Realm Kotlin підтримує Kotlin Coroutines, Flow та KSP (Kotlin Symbol Processing) для compile-time генерації коду.

RealmQuery надає type-safe API для фільтрації без SQL. Запити будуються ланцюжком методів: queryfiltersortfind. Результат може бути повернутий як список (із завантаженням у пам'ять) або як Flow (реактивний потік, що оновлюється при зміні даних). Realm Kotlin також підтримує вкладені об'єкти та списки (RealmList).

Приклад Realm Kotlin SDK

Модель даних Realm визначається як data class, що реалізує інтерфейс RealmObject. Поле _id позначено @PrimaryKey для унікальної ідентифікації. Зв'язок «один-до-багатьох» реалізується через RealmList — список інших RealmObject-ів. Всі операції запису (create, update, delete) виконуються всередині write-блоку транзакції.

kotlin
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-повертаємий запит автоматично емітує нові результати при будь-якій зміні даних у Realm: додаванні, оновленні або видаленні Project або Task. Flow-підхід ідеально поєднується з Compose: collectAsState() у ViewModel автоматично перекомпоновує UI при зміні даних без ручного оновлення адаптерів списків або використання LiveData.

Realm на iOS: Swift SDK

Realm Swift SDK надає нативний Swift API з підтримкою async/await, Combine Publishers та Swift Concurrency. Моделі даних визначаються як класи, успадковані від Object, з використанням @Persisted для властивостей. Realm Swift автоматично оновлює об'єкти при змінах, а сповіщення (NotificationToken) дозволяють підписуватися на зміни окремих об'єктів або колекцій.

@ObservedRealmObject та @ObservedResults — Property Wrappers для SwiftUI, які автоматично перемальовують View при зміні даних Realm. @ObservedResults працює з результатами запиту, @ObservedRealmObject — з конкретним об'єктом. Обидва властивості скасовують підписку при деініціалізації View.

Приклад Realm Swift SDK

SwiftUI-інтеграція Realm — одна з сильних сторін SDK. Property Wrapper @ObservedResults пов'язує запит Realm з відображенням у SwiftUI. При зміні будь-якого завдання SwiftUI автоматично перекомпоновує список. realm.writeAsync виконує транзакції на фоновому потоці без блокування UI.

swift
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) та сортування. Це усуває необхідність вручну писати fetch-запити, створювати ViewModel та підписуватися на сповіщення Realm.

Сценарії використання Realm

Офлайн-додатки — Realm ідеально підходить для сценаріїв, де дані повинні бути доступні без інтернету. Вбудована синхронізація (Realm Sync з MongoDB Atlas) автоматично вирішує конфлікти при підключенні до мережі. Додаток продовжує працювати з локальними даними, а фонова синхронізація оновлює їх при появі з'єднання.

Реактивні інтерфейси — Live Objects та Flow/Combine сповіщення роблять Realm зручним вибором для додатків з часто оновлюваними даними: чати, стрічки завдань, спільні документи. UI автоматично оновлюється при додаванні, зміні або видаленні даних без ручного виклику reloadData або invalidate.

Кросплатформні проекти — Realm підтримує Kotlin Multiplatform (KMP), Flutter, React Native та Xamarin. Модель даних визначається один раз і використовується на всіх платформах. Це скорочує дублювання коду та гарантує консистентність схеми даних між iOS та Android додатками із загальною бізнес-логікою.

Realm Sync: синхронізація через MongoDB Atlas

Realm Sync — хмарний сервіс, вбудований у MongoDB Atlas. Додаток автоматично синхронізує дані між пристроями користувача та сервером. Конфлікти вирішуються за стратегією «last write wins» або через кастомні Conflict Resolution Functions на сервері. Realm Sync підтримує часткову синхронізацію (subset of data) для зменшення трафіку.

kotlin
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 автоматично завантажує дані з хмари та об'єднує їх з локальними змінами. Синхронізація працює у фоновому потоці та не потребує ручного виклику — достатньо створити екземпляр Realm з SyncConfiguration.

Часті запитання

Realm безкоштовний для комерційного використання?

Так, локальна Realm БД повністю безкоштовна (ліцензія Apache 2.0). Realm Sync (хмарна синхронізація) через MongoDB Atlas — платний сервіс, що входить у підписку Atlas Device Sync. Для безкоштовного рівня Atlas доступні перші 500 МБ даних та 1 млн операцій на місяць.

Чи можна мігрувати з SQLite на Realm?

Так, міграція можлива через експорт даних з SQLite в JSON та імпорт у Realm при першому завантаженні додатка. Для великих обсягів використовуйте потокову міграцію: паралельно записуйте дані в обидві БД, поки користувачі не перейдуть на нову версію додатка, потім видаліть SQLite-файл.

Як Realm обробляє конфлікти синхронізації?

Realm Sync за замовчуванням використовує стратегію «last write wins» — останній запис перезаписує попередній. Для складних конфліктів налаштуйте кастомні Conflict Resolution Functions на сервері MongoDB Atlas, які об'єднують зміни з різних пристроїв за бізнес-логікою додатка (наприклад, merge значень замість заміни).

Чи підтримує Realm запити з агрегацією?

Realm не підтримує SQL-агрегації (SUM, AVG, GROUP BY) на рівні БД. Для аналітичних запитів рекомендується вивантажити дані з Realm у MongoDB Atlas через Realm Sync та виконувати агрегації через MongoDB Aggregation Pipeline. Для простих підрахунків використовуйте realm.query<T>().count().

Чи безпечні дані в Realm?

Realm не шифрує дані за замовчуванням. Для шифрування вкажіть 64-байтовий ключ у конфігурації: Realm.Configuration(encryptionKey: key). Шифрування використовує AES-256 + SHA-2 HMAC і збільшує накладні витрати на операції на 10-20%. Без шифрування файл .realm читається будь-яким процесом з доступом до файлової системи.

Підсумки

  • Realm — об'єктно-орієнтована NoSQL база даних з memory-mapped доступом, live objects та кросплатформною моделлю даних для мобільних додатків.
  • Zero-copy архітектура дозволяє читати дані безпосередньо з memory-mapped файлу без копіювання в об'єкти мови, що робить Realm на 10-50% швидшим за SQLite на читанні.
  • Live Objects та @ObservedResults (SwiftUI) / Flow (Kotlin) забезпечують автоматичне оновлення UI при зміні даних без ручних запитів до БД.
  • Realm Sync з MongoDB Atlas надає вбудовану хмарну синхронізацію з вирішенням конфліктів за стратегією «last write wins».
  • Кросплатформні SDK підтримують Kotlin Multiplatform, Flutter, React Native — модель даних визначається один раз для всіх платформ.
  • Для аналітичних запитів Realm поступається SQLite через відсутність групових агрегацій — складні звіти виконуються через MongoDB Aggregation Pipeline.
  • Рекомендація — використовуйте Realm для офлайн-додатків з частим оновленням UI та потребою в кросплатформній синхронізації, SQLite/Room — для проектів з аналітикою та стабільними наборами даних.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також