Realm nelle applicazioni mobili: cos'è e come funziona

Autore: IT Sectr Pubblicato: 2026-03-12 Tempo di lettura: 11 min

Realm è un database NoSQL orientato agli oggetti per dispositivi mobili, sviluppato come alternativa a SQLite e Core Data per iOS e Android. I dati sono memorizzati in un formato proprietario con accesso diretto agli oggetti in memoria, garantendo elevate velocità di lettura e scrittura. Grazie alle notifiche reattive, alla sincronizzazione automatica tramite Realm Sync e a un modello dati multipiattaforma, Realm è utilizzato su oltre 1 miliardo di dispositivi (dati MongoDB, 2025).

Punti chiave

  • Realm è un database NoSQL orientato agli oggetti per piattaforme mobili con accesso diretto ai dati in memoria.
  • Live Objects — gli oggetti Realm si aggiornano automaticamente quando i dati cambiano senza ricarica manuale.
  • Zero-copy — i dati non vengono copiati tra i livelli dell'applicazione, eliminando l'overhead dell'ORM.
  • Realm Sync — sincronizzazione integrata tra dispositivi tramite MongoDB Atlas Device Sync.
  • Multipiattaforma — il modello dati è definito una volta per iOS, Android, Flutter e React Native.

Cos'è Realm?

Realm è un database orientato agli oggetti creato specificamente per applicazioni mobili. A differenza di SQLite, Realm non utilizza SQL né un modello relazionale — i dati sono memorizzati come oggetti viventi (Live Objects), accessibili direttamente senza un livello ORM intermedio. Lo sviluppatore lavora con oggetti normali del linguaggio (Swift, Kotlin, Dart) che vengono automaticamente salvati nel database.

Realm è apparso nel 2014 come startup Realm Inc., ed è stato acquisito nel 2019 da MongoDB Inc. Da allora, Realm è stato sviluppato come MongoDB Realm — parte della piattaforma unificata Atlas Device Sync per la sincronizzazione dei dati mobili. Il database locale di base di Realm rimane gratuito e open source (licenza Apache 2.0), mentre Realm Sync (sincronizzazione cloud) è distribuito tramite abbonamento.

Secondo il MongoDB Developer Report (2025), Realm è utilizzato nel 15% delle applicazioni mobili come archivio locale principale. I principali casi d'uso sono applicazioni con modalità offline, modelli di oggetti complessi e necessità di sincronizzazione tra dispositivi, dove Realm supera SQLite in velocità di sviluppo e facilità di lavoro con gli oggetti.

Principi di Realm

Live Objects — ogni oggetto Realm è collegato al disco tramite un file mappato in memoria (memory-mapped file). La modifica di un oggetto in qualsiasi thread si riflette immediatamente in tutti gli altri thread senza notifica manuale. L'interfaccia utente viene ridisegnata automaticamente quando i dati cambiano tramite le notifiche di Realm. Zero-copy — Realm non copia i dati dal database negli oggetti; gli oggetti sono i dati in memoria.

Come funziona Realm: architettura e archiviazione

Il core di Realm è scritto in C++ e utilizza B+ Tree per l'indicizzazione dei dati. A differenza di SQLite, dove ogni riga è un record in una tabella relazionale, Realm memorizza gli oggetti come nodi in una struttura a grafo con riferimenti diretti tra loro (forward pointers). Le relazioni tra oggetti non sono chiavi esterne ma puntatori diretti, eliminando la necessità di operazioni JOIN.

I file Realm (estensione .realm) sono mappati in memoria (memory-mapped) — il sistema operativo stesso gestisce il caricamento delle pagine del file in memoria man mano che vengono accedute. Ciò consente a Realm di lavorare con database più grandi della RAM disponibile e fornisce una latenza di lettura a livello delle strutture dati native del linguaggio (Swift Array o Kotlin List) per i dati che rientrano nella RAM.

Zero-copy e Live Objects

File mappati in memoria — la tecnologia chiave di Realm. Invece di copiare i dati dal file del database negli oggetti del linguaggio (come fa SQLite tramite sqlite3_step + sqlite3_column_*), Realm mappa il file del database direttamente nello spazio degli indirizzi del processo. Gli oggetti del linguaggio sono semplicemente puntatori ai dati nella memoria mappata. Modificare un oggetto modifica il database sul disco senza una chiamata save separata.

CaratteristicaRealm (zero-copy)SQLite (copia)
LetturaAccesso diretto alla memoria (nanosecondi)Copia in oggetto (microsecondi)
ScritturaScrittura immediata nel file memory-mappedsave() con transazione SQL INSERT/UPDATE
RelazioniPuntatori diretti (forward pointers)Chiave esterna + JOIN
Consumo memoriaFile + cache pagine OSOggetti + cache pagine SQLite
Oggetti viventiSì (aggiornamento automatico)No (richiede nuova fetch)

Il consumo di memoria è maggiore in Realm durante la lettura attiva (l'intero file o una grande parte è mappata in memoria), ma inferiore durante le operazioni di scrittura poiché non è necessaria allocazione di memoria per copie di oggetti. Per database fino a 1 GB su dispositivi mobili, l'approccio memory-mapped offre prestazioni complessive migliori di SQLite con la sua copia intermedia.

Realm vs SQLite vs Core Data: confronto

SQLite è un DBMS relazionale con SQL e transazioni ACID. Realm è un database NoSQL orientato agli oggetti con accesso memory-mapped. Core Data è il livello ORM di Apple su SQLite. Ciascuno dei tre approcci ha il proprio ambito applicativo e punti di forza. Realm vince in velocità di accesso diretto agli oggetti e reattività, SQLite in versatilità e maturità, Core Data in integrazione con l'ecosistema Apple.

Le prestazioni di lettura di Realm sono del 10-50% superiori a SQLite grazie all'accesso zero-copy. Realm è anche più veloce in scrittura grazie all'assenza di analisi sintattica SQL e alla modifica diretta delle pagine memory-mapped. Tuttavia, Realm può consumare più RAM quando si lavora con database di grandi dimensioni (>500 MB), poiché il file è completamente mappato nello spazio degli indirizzi.

CriterioRealmSQLiteCore Data
TipoDB NoSQL orientato a oggettiDBMS relazionale (SQL)ORM su SQLite
Velocità letturaAlta (zero-copy)MediaMedia (overhead ORM)
ReattivitàLive Objects (integrata)Serve wrapper (Room/GRDB)NSFetchedResultsController
SincronizzazioneRealm Sync (MongoDB Atlas)Implementazione personalizzata necessariaNSPersistentCloudKitContainer
PiattaformeiOS, Android, Flutter, RN, Node.jsiOS, Android, Web, DesktopSolo iOS/macOS
Dimensione libreria~4 MB~600 KBIntegrato in SDK

La scelta tra Realm e SQLite spesso si riduce alle priorità: velocità di sviluppo e reattività (Realm) versus controllo e versatilità (SQLite). Realm è particolarmente indicato per MVP e prototipi dove il modello dati cambia frequentemente ed è importante ottenere aggiornamenti live dell'interfaccia rapidamente. SQLite/Room è preferibile per prodotti maturi con grandi volumi di dati e query analitiche complesse.

Realm su Android: Kotlin SDK

Realm Kotlin SDK è la libreria ufficiale per Android, scritta in Kotlin (non un wrapper su Java SDK). Il modello dati è definito tramite classi che ereditano da RealmObject, con l'annotazione @PrimaryKey per un identificatore univoco. Realm Kotlin supporta Kotlin Coroutines, Flow e KSP (Kotlin Symbol Processing) per la generazione di codice in fase di compilazione.

RealmQuery fornisce un'API type-safe per il filtraggio senza SQL. Le query sono costruite tramite una catena di metodi: queryfiltersortfind. Il risultato può essere restituito come lista (caricata in memoria) o come Flow (flusso reattivo che si aggiorna quando i dati cambiano). Realm Kotlin supporta anche oggetti annidati e liste (RealmList).

Esempio Realm Kotlin SDK

Modello dati Realm è definito come una classe dati che implementa l'interfaccia RealmObject. Il campo _id è contrassegnato con @PrimaryKey per l'identificazione univoca. La relazione uno-a-molti è implementata tramite RealmList — una lista di altri RealmObject. Tutte le operazioni di scrittura (creazione, aggiornamento, eliminazione) vengono eseguite all'interno di un blocco di transazione 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()

Una query che restituisce Flow emette automaticamente nuovi risultati a qualsiasi modifica dei dati in Realm: aggiunta, aggiornamento o eliminazione di un Project o Task. L'approccio Flow si abbina perfettamente con Compose: collectAsState() nel ViewModel ricompone automaticamente l'interfaccia quando i dati cambiano senza aggiornare manualmente gli adapter delle liste o utilizzare LiveData.

Realm su iOS: Swift SDK

Realm Swift SDK fornisce un'API Swift nativa con supporto per async/await, Combine Publishers e Swift Concurrency. I modelli dati sono definiti come classi che ereditano da Object, utilizzando @Persisted per le proprietà. Realm Swift aggiorna automaticamente gli oggetti alle modifiche e le notifiche (NotificationToken) consentono di sottoscrivere modifiche di singoli oggetti o collezioni.

@ObservedRealmObject e @ObservedResults sono Property Wrapper per SwiftUI che ridisegnano automaticamente la View quando i dati di Realm cambiano. @ObservedResults funziona con risultati di query, @ObservedRealmObject con un oggetto specifico. Entrambe le proprietà annullano la sottoscrizione quando la View viene deinizializzata.

Esempio Realm Swift SDK

Integrazione SwiftUI Realm è uno dei punti di forza dell'SDK. Il Property Wrapper @ObservedResults collega una query Realm con la visualizzazione in SwiftUI. Quando qualsiasi attività cambia, SwiftUI ricompone automaticamente la lista. realm.writeAsync esegue transazioni in un thread di background senza bloccare l'interfaccia.

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 gestisce automaticamente il ciclo di vita della query Realm: quando la View viene creata, viene creata una sottoscrizione alle modifiche; quando viene distrutta, viene annullata. Il Property Wrapper accetta un predicato opzionale (NSPredicate) e un descrittore di ordinamento. Ciò elimina la necessità di scrivere manualmente richieste fetch, creare ViewModel e sottoscrivere le notifiche di Realm.

Casi d'uso di Realm

Applicazioni offline — Realm è ideale per scenari in cui i dati devono essere disponibili senza internet. La sincronizzazione integrata (Realm Sync con MongoDB Atlas) risolve automaticamente i conflitti quando ci si connette alla rete. L'app continua a funzionare con i dati locali e la sincronizzazione in background li aggiorna quando una connessione diventa disponibile.

Interfacce reattive — Live Objects e notifiche Flow/Combine rendono Realm una scelta conveniente per applicazioni con dati che cambiano frequentemente: chat, feed di attività, documenti collaborativi. L'interfaccia si aggiorna automaticamente quando i dati vengono aggiunti, modificati o eliminati senza chiamare manualmente reloadData o invalidate.

Progetti multipiattaforma — Realm supporta Kotlin Multiplatform (KMP), Flutter, React Native e Xamarin. Il modello dati è definito una volta e utilizzato su tutte le piattaforme. Ciò riduce la duplicazione del codice e garantisce la coerenza dello schema tra applicazioni iOS e Android con logica di business condivisa.

Realm Sync: sincronizzazione tramite MongoDB Atlas

Realm Sync è un servizio cloud integrato in MongoDB Atlas. L'applicazione sincronizza automaticamente i dati tra i dispositivi dell'utente e il server. I conflitti vengono risolti con la strategia "last write wins" o tramite funzioni personalizzate di risoluzione dei conflitti sul server. Realm Sync supporta la sincronizzazione parziale (sottoinsieme di dati) per ridurre il traffico.

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)
        // La sincronizzazione automatica è attiva
    }
}

SyncConfiguration configura la connessione a MongoDB Atlas e definisce l'insieme di modelli da sincronizzare. Dopo l'autenticazione dell'utente, Realm carica automaticamente i dati dal cloud e li unisce con le modifiche locali. La sincronizzazione viene eseguita in un thread di background e non richiede chiamate manuali — basta creare un'istanza Realm con SyncConfiguration.

Domande frequenti

Realm è gratuito per uso commerciale?

Sì, il database locale Realm è completamente gratuito (licenza Apache 2.0). Realm Sync (sincronizzazione cloud) tramite MongoDB Atlas è un servizio a pagamento incluso nell'abbonamento Atlas Device Sync. Il livello gratuito di Atlas include i primi 500 MB di dati e 1 milione di operazioni al mese.

Si può migrare da SQLite a Realm?

Sì, la migrazione è possibile esportando i dati da SQLite in JSON e importandoli in Realm al primo caricamento dell'applicazione. Per volumi elevati, utilizzare la migrazione in streaming: scrivere i dati in entrambi i database in parallelo mentre gli utenti passano alla nuova versione dell'app, quindi eliminare il file SQLite.

Come gestisce Realm i conflitti di sincronizzazione?

Realm Sync utilizza per impostazione predefinita la strategia "last write wins" — l'ultima scrittura sovrascrive la precedente. Per conflitti complessi, configurare funzioni personalizzate di risoluzione dei conflitti sul server MongoDB Atlas che uniscono le modifiche da diversi dispositivi secondo la logica di business dell'applicazione (ad esempio, unire i valori invece di sostituirli).

Realm supporta query di aggregazione?

Realm non supporta aggregazioni SQL (SUM, AVG, GROUP BY) a livello di database. Per query analitiche, si consiglia di esportare i dati da Realm a MongoDB Atlas tramite Realm Sync ed eseguire aggregazioni tramite MongoDB Aggregation Pipeline. Per conteggi semplici, utilizzare realm.query<T>().count().

I dati in Realm sono sicuri?

Realm non crittografa i dati per impostazione predefinita. Per la crittografia, fornire una chiave a 64 byte nella configurazione: Realm.Configuration(encryptionKey: key). La crittografia utilizza AES-256 + SHA-2 HMAC e aumenta l'overhead delle operazioni del 10-20%. Senza crittografia, il file .realm può essere letto da qualsiasi processo con accesso al filesystem.

Riepilogo

  • Realm è un database NoSQL orientato agli oggetti con accesso memory-mapped, oggetti viventi e modello dati multipiattaforma per applicazioni mobili.
  • L'architettura Zero-copy consente di leggere i dati direttamente da un file mappato in memoria senza copiarli in oggetti del linguaggio, rendendo Realm 10-50% più veloce di SQLite in lettura.
  • Live Objects e @ObservedResults (SwiftUI) / Flow (Kotlin) forniscono aggiornamenti automatici dell'interfaccia quando i dati cambiano senza query manuali al database.
  • Realm Sync con MongoDB Atlas fornisce sincronizzazione cloud integrata con risoluzione dei conflitti tramite la strategia "last write wins".
  • SDK multipiattaforma supportano Kotlin Multiplatform, Flutter, React Native — il modello dati è definito una volta per tutte le piattaforme.
  • Per query analitiche Realm è inferiore a SQLite a causa della mancanza di aggregazioni di gruppo — i report complessi vengono eseguiti tramite MongoDB Aggregation Pipeline.
  • Raccomandazione — utilizzare Realm per applicazioni offline con aggiornamenti frequenti dell'interfaccia e necessità di sincronizzazione multipiattaforma, SQLite/Room per progetti con analisi e set di dati stabili.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche