Realm — мобильная объектно-ориентированная NoSQL база данных, разработанная как альтернатива SQLite и Core Data для iOS и Android. Данные хранятся в собственном формате с прямым доступом к объектам в памяти, что обеспечивает высокую скорость чтения и записи. Благодаря реактивным уведомлениям, автоматической синхронизации через Realm Sync и кросс-платформенной модели данных, Realm используется более чем в 1 миллиарде устройств (данные 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 связан с диском через отображение в память (memory-mapped file). Изменение объекта в любом потоке немедленно отражается во всех других потоках без ручного уведомления. Интерфейс UI автоматически перерисовывается при изменении данных через Realm-уведомления. Zero-copy — Realm не копирует данные из БД в объекты, объекты — это и есть данные в памяти.
Ядро Realm написано на C++ и использует B+ Tree для индексации данных. В отличие от SQLite, где каждая строка — это запись в реляционной таблице, Realm хранит объекты как узлы в графовой структуре с прямыми ссылками между ними (forward pointers). Связи между объектами — это не foreign keys, а прямые указатели, что устраняет необходимость в JOIN-операциях.
Файлы Realm (расширение .realm) являются memory-mapped — ОС сама управляет загрузкой страниц файла в память по мере обращения. Это позволяет Realm работать с базами, превышающими доступную оперативную память, и обеспечивает read latency на уровне нативных структур данных языка (Swift Array или Kotlin List) для данных, умещающихся в RAM.
Memory-mapped файлы — ключевая технология Realm. Вместо того чтобы копировать данные из файла БД в объекты языка (как делает SQLite через sqlite3_step + sqlite3_column_*), Realm отображает файл базы прямо в адресное пространство процесса. Объекты языка — это просто указатели на данные в отображённой памяти. Изменение объекта меняет базу на диске без отдельного save-вызова.
| Характеристика | Realm (zero-copy) | SQLite (копирование) |
|---|---|---|
| Чтение | Прямой доступ к памяти (наносекунды) | Копирование в объект (микросекунды) |
| Запись | Немедленная запись в memory-mapped file | save() с транзакцией SQL INSERT/UPDATE |
| Связи | Прямые указатели (forward pointers) | Foreign key + JOIN |
| Потребление памяти | Файл + кеш страниц ОС | Объекты + кеш страниц SQLite |
| Живые объекты | Да (автоматическое обновление) | Нет (требуется новый fetch) |
Потребление памяти Realm выше при активном чтении (весь файл или его большая часть отображена в память), но ниже при операциях записи, так как не требуется выделение памяти под копии объектов. Для баз размером до 1 ГБ на мобильных устройствах memory-mapped подход даёт лучшую общую производительность, чем SQLite с его промежуточным копированием.
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 МБ), так как файл полностью отображается в адресное пространство.
| Критерий | Realm | SQLite | Core Data |
|---|---|---|---|
| Тип | NoSQL объектная БД | Реляционная СУБД (SQL) | ORM поверх SQLite |
| Скорость чтения | Высокая (zero-copy) | Средняя | Средняя (ORM overhead) |
| Реактивность | Live Objects (встроена) | Нужна обёртка (Room/GRDB) | NSFetchedResultsController |
| Синхронизация | Realm Sync (MongoDB Atlas) | Требуется кастомная реализация | NSPersistentCloudKitContainer |
| Платформы | iOS, Android, Flutter, RN, Node.js | iOS, Android, Web, Desktop | Только iOS/macOS |
| Размер библиотеки | ~4 МБ | ~600 КБ | Встроен в SDK |
Выбор между Realm и SQLite часто сводится к приоритетам: скорость разработки и реактивность (Realm) против контроля и универсальности (SQLite). Realm особенно хорош для MVP и прототипов, где модель данных меняется часто и важно быстро получать живые обновления UI. SQLite/Room предпочтительнее для зрелых продуктов с большими объёмами данных и сложными аналитическими запросами.
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. Запросы строятся цепочкой методов: query → filter → sort → find. Результат может быть возвращён как список (с загрузкой в память) или как Flow (реактивный стрим, обновляющийся при изменении данных). Realm Kotlin также поддерживает вложенные объекты и списки (RealmList).
Модель данных Realm определяется как data class, реализующий интерфейс RealmObject. Поле _id помечено @PrimaryKey для уникальной идентификации. Связь "один-ко-многим" реализуется через RealmList — список других RealmObject-ов. Все операции записи (create, update, delete) выполняются внутри 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-возвращаемый запрос автоматически эмитит новые результаты при любом изменении данных в Realm: добавлении, обновлении или удалении Project или Task. Flow-подход идеально сочетается с Compose: collectAsState() в ViewModel автоматически перекомпоновывает UI при изменении данных без ручного обновления адаптеров списков или использования LiveData.
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.
SwiftUI-интеграция Realm — одна из сильных сторон SDK. Property Wrapper @ObservedResults связывает запрос 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) и сортировку. Это устраняет необходимость вручную писать fetch-запросы, создавать ViewModel и подписываться на уведомления 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. Приложение автоматически синхронизирует данные между устройствами пользователя и сервером. Конфликты разрешаются по стратегии "last write wins" или через кастомные Conflict Resolution Functions на сервере. Realm Sync поддерживает частичную синхронизацию (subset of data) для уменьшения трафика.
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 БД полностью бесплатна (лицензия Apache 2.0). Realm Sync (облачная синхронизация) через MongoDB Atlas — платный сервис, входящий в подписку Atlas Device Sync. Для бесплатного уровня Atlas доступны первые 500 МБ данных и 1 млн операций в месяц.
Да, миграция возможна через экспорт данных из SQLite в JSON и импорт в Realm на первой загрузке приложения. Для больших объёмов используйте потоковую миграцию: параллельно записывайте данные в обе БД, пока пользователи не перейдут на новую версию приложения, затем удалите SQLite-файл.
Realm Sync по умолчанию использует стратегию "last write wins" — последняя запись перезаписывает предыдущую. Для сложных конфликтов настройте кастомные Conflict Resolution Functions на сервере MongoDB Atlas, которые объединяют изменения из разных устройств по бизнес-логике приложения (например, merge значений вместо замены).
Realm не поддерживает SQL-агрегации (SUM, AVG, GROUP BY) на уровне БД. Для аналитических запросов рекомендуется выгрузить данные из Realm в MongoDB Atlas через Realm Sync и выполнять агрегации через MongoDB Aggregation Pipeline. Для простых подсчётов используйте realm.query.
Realm не шифрует данные по умолчанию. Для шифрования укажите 64-байтовый ключ в конфигурации: Realm.Configuration(encryptionKey: key). Шифрование использует AES-256 + SHA-2 HMAC и увеличивает накладные расходы на операции на 10-20%. Без шифрования файл .realm читается любым процессом с доступом к файловой системе.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также