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 файл. Промяна на обект в който и да е поток незабавно се отразява във всички други потоци без ръчно уведомление. Потребителският интерфейс автоматично се прерисува при промяна на данни чрез известия на Realm. Zero-copy Realm не копира данни от базата данни в обекти, обектите са самите данни в паметта.
Ядрото на Realm е написано на C++ и използва B+ Tree за индексиране на данни. За разлика от SQLite, където всеки ред е запис в релационна таблица, Realm съхранява обекти като възли в графова структура с директни препратки между тях (forward pointers). Връзките между обекти не са foreign keys, а директни указатели, което елиминира необходимостта от JOIN операции.
Файловете на Realm (разширение .realm) са memory-mapped — операционната система сама управлява зареждането на страници от файла в паметта при достъп. Това позволява на Realm да работи с бази данни, надвишаващи наличната оперативна памет, и осигурява латентност на четене на нивото на родните езикови структури от данни (Swift Array или Kotlin List) за данни, които се побират в RAM.
Memory-mapped файлове са ключовата технология на Realm. Вместо да копира данни от файла на базата данни в езикови обекти (както прави SQLite чрез sqlite3_step + sqlite3_column_*), Realm картира файла на базата данни директно в адресното пространство на процеса. Езиковите обекти са просто указатели към данни в картираната памет. Промяната на обект променя базата данни на диска без отделно извикване на save.
| Характеристика | Realm (zero-copy) | SQLite (копиране) |
|---|---|---|
| Четене | Директен достъп до паметта (наносекунди) | Копиране в обект (микросекунди) |
| Запис | Незабавен запис в memory-mapped файл | save() с транзакция SQL INSERT/UPDATE |
| Връзки | Директни указатели (forward pointers) | Foreign key + JOIN |
| Консумация на памет | Файл + кеш на страниците на ОС | Обекти + кеш на страниците на SQLite |
| Живи обекти | Да (автоматична актуализация) | Не (изисква се ново fetch) |
Консумацията на памет на Realm е по-висока при активно четене (целият файл или голяма част от него е картографиран в паметта), но по-ниска при операции по запис, тъй като не се изисква заделяне на памет за копия на обекти. За бази данни до 1 GB на мобилни устройства, 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 MB), тъй като файлът е изцяло картографиран в адресното пространство.
| Критерий | Realm | SQLite | Core Data |
|---|---|---|---|
| Тип | NoSQL обектна база данни | Релационна СУБД (SQL) | ORM върху SQLite |
| Скорост на четене | Висока (zero-copy) | Средна | Средна (ORM тежест) |
| Реактивност | Live Objects (вградена) | Нужна е обвивка (Room/GRDB) | NSFetchedResultsController |
| Синхронизация | Realm Sync (MongoDB Atlas) | Изисква персонализирана реализация | NSPersistentCloudKitContainer |
| Платформи | iOS, Android, Flutter, RN, Node.js | iOS, Android, Web, Desktop | Само iOS/macOS |
| Размер на библиотеката | ~4 MB | ~600 KB | Вграден в 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) за генериране на код по време на компилация.
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 Wrapper-и за 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("Добавяне на задача") {
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 поддържа частична синхронизация (подмножество от данни) за намаляване на трафика.
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 MB данни и 1 милион операции на месец.
Да, миграцията е възможна чрез експортиране на данни от SQLite в JSON и импортиране в Realm при първото зареждане на приложението. За големи обеми използвайте поточна миграция: записвайте данни паралелно и в двете бази данни, докато потребителите преминат към новата версия на приложението, след което изтрийте SQLite файла.
Realm Sync по подразбиране използва стратегията „last write wins” — последният запис презаписва предишния. За сложни конфликти конфигурирайте персонализирани Conflict Resolution Functions на сървъра MongoDB Atlas, които обединяват промени от различни устройства според бизнес логиката на приложението (например обединяване на стойности вместо замяна).
Realm не поддържа SQL агрегации (SUM, AVG, GROUP BY) на ниво база данни. За аналитични заявки се препоръчва експортиране на данни от Realm в MongoDB Atlas чрез Realm Sync и изпълнение на агрегации чрез MongoDB Aggregation Pipeline. За прости преброявания използвайте realm.query<T>().count().
Realm не криптира данни по подразбиране. За криптиране посочете 64-байтов ключ в конфигурацията: Realm.Configuration(encryptionKey: key). Криптирането използва AES-256 + SHA-2 HMAC и увеличава допълнителната тежест на операциите с 10-20%. Без криптиране, .realm файлът може да бъде прочетен от всеки процес с достъп до файловата система.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също