Realm w aplikacjach mobilnych: co to jest i jak działa

Autor: IT Sectr Opublikowano: 2026-03-12 Czas czytania: 11 min

Realm — mobilna, zorientowana obiektowo baza danych NoSQL, opracowana jako alternatywa dla SQLite i Core Data dla iOS i Android. Dane są przechowywane we własnym formacie z bezpośrednim dostępem do obiektów w pamięci, co zapewnia wysoką szybkość odczytu i zapisu. Dzięki reaktywnym powiadomieniom, automatycznej synchronizacji przez Realm Sync i wieloplatformowemu modelowi danych, Realm jest używany na ponad 1 miliardzie urządzeń (dane MongoDB, 2025).

Najważniejsze

  • Realm — obiektowa baza NoSQL dla platform mobilnych z bezpośrednim dostępem do danych w pamięci RAM.
  • Live Objects — obiekty Realm automatycznie aktualizują się przy zmianie danych bez ręcznego przeładowywania.
  • Zero-copy — dane nie są kopiowane między warstwami aplikacji, co eliminuje narzut ORM.
  • Realm Sync — wbudowana synchronizacja między urządzeniami przez MongoDB Atlas Device Sync.
  • Wieloplatformowość — model danych definiuje się raz dla iOS, Android, Flutter i React Native.

Czym jest Realm?

Realm — to zorientowana obiektowo baza danych stworzona specjalnie dla aplikacji mobilnych. W przeciwieństwie do SQLite, Realm nie używa SQL ani modelu relacyjnego — dane są przechowywane jako żywe obiekty (Live Objects), do których dostęp odbywa się bezpośrednio, bez pośredniczącej warstwy ORM. Deweloper pracuje ze zwykłymi obiektami języka (Swift, Kotlin, Dart), które automatycznie zapisują się w bazie.

Realm pojawił się w 2014 roku jako startup Realm Inc., a w 2019 roku został przejęty przez MongoDB Inc. Od tego czasu Realm rozwija się jako MongoDB Realm — część jednolitej platformy Atlas Device Sync do mobilnej synchronizacji danych. Podstawowa lokalna baza Realm pozostaje bezpłatna i otwarta (licencja Apache 2.0), a Realm Sync (synchronizacja w chmurze) jest dostępny w subskrypcji.

Według MongoDB Developer Report (2025), Realm jest używany w 15% aplikacji mobilnych jako główne lokalne przechowywanie. Główne scenariusze to aplikacje z trybem offline, złożonymi modelami obiektowymi i potrzebą synchronizacji między urządzeniami, gdzie Realm przewyższa SQLite szybkością tworzenia i wygodą pracy z obiektami.

Zasady Realm

Live Objects — każdy obiekt Realm jest powiązany z dyskiem poprzez mapowanie pamięci (memory-mapped file). Zmiana obiektu w dowolnym wątku natychmiast odbija się we wszystkich innych wątkach bez ręcznego powiadamiania. Interfejs UI automatycznie przerysowuje się przy zmianie danych przez powiadomienia Realm. Zero-copy — Realm nie kopiuje danych z bazy do obiektów, obiekty to dane w pamięci.

Jak zbudowany jest Realm: architektura i przechowywanie

Jądro Realm jest napisane w C++ i używa B+ Tree do indeksowania danych. W przeciwieństwie do SQLite, gdzie każdy wiersz to rekord w tabeli relacyjnej, Realm przechowuje obiekty jako węzły w strukturze grafowej z bezpośrednimi referencjami między nimi (forward pointers). Relacje między obiektami to nie klucze obce, ale bezpośrednie wskaźniki, co eliminuje potrzebę operacji JOIN.

Pliki Realm (rozszerzenie .realm) są memory-mapped — system operacyjny sam zarządza ładowaniem stron pliku do pamięci podczas dostępu. Pozwala to Realm pracować z bazami przekraczającymi dostępną pamięć RAM i zapewnia opóźnienie odczytu na poziomie natywnych struktur danych języka (Swift Array lub Kotlin List) dla danych mieszczących się w RAM.

Zero-copy i Live Objects

Pliki memory-mapped — kluczowa technologia Realm. Zamiast kopiować dane z pliku bazy do obiektów języka (jak robi SQLite przez sqlite3_step + sqlite3_column_*), Realm odwzorowuje plik bazy bezpośrednio w przestrzeń adresową procesu. Obiekty języka to po prostu wskaźniki do danych w odwzorowanej pamięci. Zmiana obiektu modyfikuje bazę na dysku bez osobnego wywołania save.

CechaRealm (zero-copy)SQLite (kopiowanie)
OdczytBezpośredni dostęp do pamięci (nanosekundy)Kopiowanie do obiektu (mikrosekundy)
ZapisNatychmiastowy zapis do memory-mapped filesave() z transakcją SQL INSERT/UPDATE
RelacjeBezpośrednie wskaźniki (forward pointers)Foreign key + JOIN
Zużycie pamięciPlik + cache stron systemuObiekty + cache stron SQLite
Żywe obiektyTak (automatyczna aktualizacja)Nie (wymagany nowy fetch)

Zużycie pamięci Realm jest wyższe przy aktywnym odczycie (cały plik lub jego duża część jest odwzorowana w pamięci), ale niższe przy operacjach zapisu, ponieważ nie wymaga alokacji pamięci dla kopii obiektów. Dla baz o rozmiarze do 1 GB na urządzeniach mobilnych podejście memory-mapped daje lepszą ogólną wydajność niż SQLite z jego pośrednim kopiowaniem.

Realm vs SQLite vs Core Data: porównanie

SQLite — relacyjny system zarządzania bazami danych z SQL i transakcjami ACID. Realm — obiektowa baza NoSQL z dostępem memory-mapped. Core Data — warstwa ORM Apple na SQLite. Każde z trzech podejść ma swój obszar zastosowania i mocne strony. Realm wygrywa w szybkości bezpośredniego dostępu do obiektów i reaktywności, SQLite — w uniwersalności i dojrzałości, Core Data — w integracji z ekosystemem Apple.

Wydajność Realm w operacjach odczytu jest o 10-50% wyższa niż SQLite dzięki dostępowi zero-copy. W operacjach zapisu Realm jest również szybszy dzięki brakowi analizy składniowej SQL i bezpośredniej modyfikacji stron memory-mapped. Jednak Realm może zużywać więcej pamięci RAM przy pracy z dużymi bazami (>500 MB), ponieważ plik jest w pełni odwzorowywany w przestrzeń adresową.

KryteriumRealmSQLiteCore Data
TypNoSQL obiektowa bazaRelacyjna SZBD (SQL)ORM na SQLite
Prędkość odczytuWysoka (zero-copy)ŚredniaŚrednia (narzut ORM)
ReaktywnośćLive Objects (wbudowana)Wymaga otoczki (Room/GRDB)NSFetchedResultsController
SynchronizacjaRealm Sync (MongoDB Atlas)Wymaga własnej implementacjiNSPersistentCloudKitContainer
PlatformyiOS, Android, Flutter, RN, Node.jsiOS, Android, Web, DesktopTylko iOS/macOS
Rozmiar biblioteki~4 MB~600 KBWbudowane w SDK

Wybór między Realm a SQLite często sprowadza się do priorytetów: szybkość tworzenia i reaktywność (Realm) przeciwko kontroli i uniwersalności (SQLite). Realm jest szczególnie dobry dla MVP i prototypów, gdzie model danych zmienia się często i ważne jest szybkie otrzymywanie żywych aktualizacji UI. SQLite/Room jest preferowany dla dojrzałych produktów z dużymi wolumenami danych i złożonymi zapytaniami analitycznymi.

Realm na Android: Kotlin SDK

Realm Kotlin SDK — oficjalna biblioteka dla Androida, napisana w Kotlin (nie otoczka nad Java SDK). Model danych jest definiowany przez klasy dziedziczące po RealmObject, z adnotacją @PrimaryKey dla unikalnego identyfikatora. Realm Kotlin wspiera Kotlin Coroutines, Flow i KSP (Kotlin Symbol Processing) do generowania kodu w czasie kompilacji.

RealmQuery zapewnia type-safe API do filtrowania bez SQL. Zapytania buduje się łańcuchem metod: queryfiltersortfind. Wynik może być zwrócony jako lista (z załadowaniem do pamięci) lub jako Flow (reaktywny strumień, aktualizujący się przy zmianie danych). Realm Kotlin wspiera również zagnieżdżone obiekty i listy (RealmList).

Przykład Realm Kotlin SDK

Model danych Realm jest definiowany jako data class implementująca interfejs RealmObject. Pole _id jest oznaczone @PrimaryKey dla unikalnej identyfikacji. Relacja jednen-do-wielu jest realizowana przez RealmList — listę innych RealmObject-ów. Wszystkie operacje zapisu (create, update, delete) są wykonywane wewnątrz bloku transakcji 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()

Zapytanie zwracające Flow automatycznie emituje nowe wyniki przy każdej zmianie danych w Realm: dodaniu, aktualizacji lub usunięciu Project lub Task. Podejście Flow idealnie współgra z Compose: collectAsState() w ViewModel automatycznie przebudowuje UI przy zmianie danych bez ręcznego aktualizowania adapterów list lub używania LiveData.

Realm na iOS: Swift SDK

Realm Swift SDK zapewnia natywne Swift API z obsługą async/await, Combine Publishers i Swift Concurrency. Modele danych są definiowane jako klasy dziedziczące po Object, z użyciem @Persisted dla właściwości. Realm Swift automatycznie aktualizuje obiekty przy zmianach, a powiadomienia (NotificationToken) pozwalają subskrybować zmiany poszczególnych obiektów lub kolekcji.

@ObservedRealmObject i @ObservedResults — Property Wrappers dla SwiftUI, które automatycznie przerysowują View przy zmianie danych Realm. @ObservedResults działa z wynikami zapytania, @ObservedRealmObject — z konkretnym obiektem. Obie właściwości anulują subskrypcję przy deinicjalizacji View.

Przykład Realm Swift SDK

Integracja Realm ze SwiftUI — jedna z mocnych stron SDK. Property Wrapper @ObservedResults łączy zapytanie Realm z wyświetlaniem w SwiftUI. Przy zmianie dowolnego zadania SwiftUI automatycznie przebudowuje listę. realm.writeAsync wykonuje transakcje w wątku tła bez blokowania 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("Dodaj zadanie") {
            let realm = try! Realm()
            try! realm.write {
                realm.add(TaskItem(value: ["title": "New task"]))
            }
        }
    }
}

@ObservedResults automatycznie zarządza cyklem życia zapytania Realm: przy tworzeniu View tworzona jest subskrypcja zmian, przy zniszczeniu — anulowana. Property Wrapper przyjmuje opcjonalny predykat (NSPredicate) i sortowanie. Eliminuje to konieczność ręcznego pisania zapytań fetch, tworzenia ViewModel i subskrybowania powiadomień Realm.

Scenariusze użycia Realm

Aplikacje offline — Realm idealnie nadaje się do scenariuszy, gdzie dane muszą być dostępne bez internetu. Wbudowana synchronizacja (Realm Sync z MongoDB Atlas) automatycznie rozwiązuje konflikty przy połączeniu z siecią. Aplikacja nadal pracuje z lokalnymi danymi, a synchronizacja w tle aktualizuje je po pojawieniu się połączenia.

Interfejsy reaktywne — Live Objects i powiadomienia Flow/Combine czynią Realm wygodnym wyborem dla aplikacji z często aktualizowanymi danymi: czaty, listy zadań, dokumenty współdzielone. UI automatycznie aktualizuje się przy dodawaniu, zmianie lub usuwaniu danych bez ręcznego wywoływania reloadData lub invalidate.

Projekty wieloplatformowe — Realm wspiera Kotlin Multiplatform (KMP), Flutter, React Native i Xamarin. Model danych definiuje się raz i używa na wszystkich platformach. Zmniejsza to powielanie kodu i gwarantuje spójność schematu danych między aplikacjami iOS i Android ze wspólną logiką biznesową.

Realm Sync: synchronizacja przez MongoDB Atlas

Realm Sync — usługa w chmurze wbudowana w MongoDB Atlas. Aplikacja automatycznie synchronizuje dane między urządzeniami użytkownika a serwerem. Konflikty są rozwiązywane według strategii last write wins lub przez niestandardowe Conflict Resolution Functions na serwerze. Realm Sync wspiera częściową synchronizację (subset of data) w celu zmniejszenia ruchu.

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)
        // Automatyczna synchronizacja aktywna
    }
}

SyncConfiguration konfiguruje połączenie z MongoDB Atlas i określa zestaw synchronizowanych modeli. Po uwierzytelnieniu użytkownika Realm automatycznie ładuje dane z chmury i łączy je z lokalnymi zmianami. Synchronizacja działa w wątku tła i nie wymaga ręcznego wywoływania — wystarczy utworzyć instancję Realm z SyncConfiguration.

Często zadawane pytania

Czy Realm jest darmowy do użytku komercyjnego?

Tak, lokalna Realm baza danych jest całkowicie darmowa (licencja Apache 2.0). Realm Sync (synchronizacja w chmurze) przez MongoDB Atlas to płatna usługa wchodząca w skład subskrypcji Atlas Device Sync. Darmowy poziom Atlas oferuje pierwsze 500 MB danych i 1 milion operacji miesięcznie.

Czy można migrować z SQLite na Realm?

Tak, migracja jest możliwa przez eksport danych z SQLite do JSON i import do Realm przy pierwszym uruchomieniu aplikacji. Dla dużych wolumenów użyj migracji strumieniowej: równolegle zapisuj dane do obu baz, aż użytkownicy przejdą na nową wersję aplikacji, następnie usuń plik SQLite.

Jak Realm obsługuje konflikty synchronizacji?

Realm Sync domyślnie używa strategii last write wins — ostatni zapis nadpisuje poprzedni. Dla złożonych konfliktów skonfiguruj niestandardowe Conflict Resolution Functions na serwerze MongoDB Atlas, które łączą zmiany z różnych urządzeń według logiki biznesowej aplikacji (np. scalanie wartości zamiast zastępowania).

Czy Realm obsługuje zapytania agregujące?

Realm nie obsługuje agregacji SQL (SUM, AVG, GROUP BY) na poziomie bazy. Do zapytań analitycznych zaleca się eksport danych z Realm do MongoDB Atlas przez Realm Sync i wykonywanie agregacji przez MongoDB Aggregation Pipeline. Do prostych obliczeń użyj realm.query&lt;T&gt;().count().

Czy dane w Realm są bezpieczne?

Realm nie szyfruje danych domyślnie. Do szyfrowania podaj 64-bajtowy klucz w konfiguracji: Realm.Configuration(encryptionKey: key). Szyfrowanie używa AES-256 + SHA-2 HMAC i zwiększa narzut operacji o 10-20%. Bez szyfrowania plik .realm może być odczytany przez dowolny proces z dostępem do systemu plików.

Podsumowanie

  • Realm — zorientowana obiektowo baza danych NoSQL z dostępem memory-mapped, live objects i wieloplatformowym modelem danych dla aplikacji mobilnych.
  • Architektura Zero-copy pozwala czytać dane bezpośrednio z pliku memory-mapped bez kopiowania do obiektów języka, co czyni Realm o 10-50% szybszym od SQLite przy odczycie.
  • Live Objects i @ObservedResults (SwiftUI) / Flow (Kotlin) zapewniają automatyczną aktualizację UI przy zmianie danych bez ręcznych zapytań do bazy.
  • Realm Sync z MongoDB Atlas zapewnia wbudowaną synchronizację w chmurze z rozwiązywaniem konfliktów według strategii last write wins.
  • Wieloplatformowe SDK wspierają Kotlin Multiplatform, Flutter, React Native — model danych definiuje się raz dla wszystkich platform.
  • Do zapytań analitycznych Realm ustępuje SQLite z powodu braku agregacji grupowych — złożone raporty wykonuje się przez MongoDB Aggregation Pipeline.
  • Zalecenie — używaj Realm do aplikacji offline z częstymi aktualizacjami UI i potrzebą synchronizacji międzyplatformowej, SQLite/Room — do projektów z analityką i stabilnymi zestawami danych.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również