SQLite în dezvoltarea mobilă: ce este și cum funcționează

Autor: IT Sectr Publicat: 2026-03-11 Timp de citire: 10 min

SQLite este o bază de date relațională încorporată care funcționează fără un proces server separat și stochează întreaga bază de date într-un singur fișier pe dispozitiv. Datorită configurării zero, dimensiunii reduse a bibliotecii și suportului complet pentru SQL, SQLite a devenit standardul pentru stocarea locală a datelor în aplicațiile mobile. Conform datelor SQLite Consortium (2025), acest SGBD este utilizat în peste 4 miliarde de dispozitive, inclusiv fiecare smartphone pe iOS și Android.

Principalele idei

  • SQLite — SGBD relațional încorporat cu configurare zero și stocare a datelor într-un singur fișier.
  • Tranzacțiile ACID — garantează integritatea datelor chiar și în caz de cădere de curent sau crash al aplicației.
  • Tipizarea datelor — dinamică: SQLite nu necesită specificarea strictă a tipului coloanei la crearea tabelului.
  • Room — biblioteca ORM pentru Android care simplifică lucrul cu SQLite prin DAO și adnotări.
  • CoreData poate folosi SQLite ca Persistent Store pe iOS, dar adaugă un strat de gestionare a obiectelor.

Ce este SQLite?

SQLite este o bibliotecă în limbajul C care implementează un SGBD relațional fără server dedicat. Este încorporată direct în aplicație, citește și scrie date într-un fișier obișnuit pe sistemul de fișiere al dispozitivului. Dimensiunea bibliotecii este de aproximativ 600 KB, ceea ce face din SQLite cea mai ușoară bază de date SQL complet funcțională.

SQLite suportă cea mai mare parte a standardului SQL:1999, inclusiv JOIN, subinterogări, declanșatoare, vizualizări, indecși și funcții fereastră. Limitările se referă la ALTER TABLE (suport limitat) și la RIGHT/FULL OUTER JOIN complete. Cu toate acestea, pentru aplicațiile mobile, funcționalitatea SQLite este suficientă în 99% din cazurile de stocare locală.

Conform sondajului dezvoltatorilor de pe Stack Overflow (2025), SQLite este cea mai populară bază de date pentru soluții încorporate și ocupă locul trei ca popularitate între toate SGBD-urile, după MySQL și PostgreSQL. În dezvoltarea mobilă, SQLite este folosită în fiecare aplicație — direct sau prin intermediul unor stratificări.

Caracteristicile cheie ale SQLite

Zero-configuration — SQLite nu necesită instalare, configurare a permisiunilor, creare de utilizatori sau pornirea unui serviciu. Biblioteca se conectează la proiect, iar baza de date se creează prin apelarea unei singure funcții. Acest lucru simplifică radical implementarea în comparație cu SGBD-urile client-server, care necesită instalarea serverului, configurarea porturilor și configurarea utilizatorilor.

Fișierul bazei de date SQLite este un fișier obișnuit cross-platform care poate fi copiat, analizat, trimis prin rețeaua sau restaurat dintr-o copie de rezervă. Formatul fișierului este stabil la nivel de API: fișierele SQLite 3 create în 2004 se deschid cu versiunea curentă a bibliotecii, ceea ce garantează compatibilitatea pe termen lung a datelor.

Cum este structurat SQLite: arhitectură și stocare

Arhitectura SQLite constă din opt mașini virtuale: Tokenizer, Parser, Code Generator, VM, B-Tree, Pager, OS Interface și Utilities. O interogare SQL trece prin Tokenizer (împărțire în tokeni), Parser (construirea AST), Code Generator (conversia în cod de octeți) și este executată pe mașina virtuală care citește paginile de date prin B-Tree și Pager.

SQLite utilizează B-Tree pentru stocarea tabelelor și indecșilor. Fiecare tabelă este stocată ca un B-Tree separat, unde nodurile frunză conțin rândurile de date. Indecșii sunt de asemenea stocați ca B-Tree, dar cu chei în frunze. Pager gestionează încărcarea paginilor (implicit 4096 de octeți) din fișier în memorie, asigurând tranzacții ACID prin jurnal sau WAL.

Moduri de jurnalizare

WAL (Write-Ahead Logging) — modul recomandat pentru aplicațiile mobile. Modificările sunt scrise mai întâi într-un fișier WAL separat, apoi transferate periodic în baza de date principală. WAL permite citirea simultană din baza de date (date vechi) și scrierea în ea (prin WAL), ceea ce îmbunătățește performanța aplicațiilor multi-threaded. Jurnalul standard (rollback journal) blochează citirea în timpul scrierii.

ParametruRollback JournalWAL (Write-Ahead Logging)
Citirea în timpul scrieriiBlocatăPermisă (citește date vechi)
Performanța scrieriiMedieRidicată (scriere secvențială în WAL)
Consumul de discMai mic (doar jurnalul de revenire)Mai mare (WAL + baza principală)
Recuperarea după avarieRevenire la ultimul punct de controlRecuperare din WAL (datele nu se pierd)
RecomandarePentru scenarii single-threadPentru aplicații mobile tipice

Comutarea între moduri se face cu o singură interogare SQL: PRAGMA journal_mode=WAL. Pentru aplicațiile mobile cu sincronizare în fundal și un fir UI care citește simultan datele, WAL oferă o performanță mai bună și fără blocarea interfeței.

SQLite vs alte baze de date în dezvoltarea mobilă

SQLite nu este singura opțiune pentru stocarea locală a datelor, dar este cea mai universală. Realm oferă o viteză mai mare de acces direct la obiectele din memorie, dar folosește propriul format NoSQL și are o dimensiune mai mare a bibliotecii. Core Data pe iOS este un strat ORM peste SQLite care adaugă gestionarea grafului de obiecte și anularea operațiilor.

Pentru majoritatea aplicațiilor, SQLite rămâne alegerea optimă datorită performanței previzibile, lipsei de dependență de vendor și stabilității testate în timp. Realm și Core Data sunt justificate în proiecte cu grafuri complexe de obiecte, interogări reactive sau cerințe de sincronizare între dispozitive.

CaracteristicăSQLiteRealmCore Data
Tipul bazei de dateRelațională (SQL)NoSQL (orientată pe obiecte)ORM (peste SQLite)
Dimensiunea bibliotecii~600 KB~4 MBÎncorporată în SDK-ul Apple
PerformanțaMedieRidicată (obiecte în memorie)Medie (supliment ORM)
PlatformeiOS, Android, Web, DesktopiOS, Android, Node.jsiOS, macOS
Dependența de vendorNu (standard deschis)Medie (format propriu)Ridicată (doar Apple)

Alegerea între SQLite, Realm și Core Data depinde de platformă, cerințele modelului de obiecte și strategia de sincronizare. Pentru proiecte cross-platform (KMP, Flutter), SQLite rămâne singura alegere universală care funcționează pe toate platformele țintă fără modificări ale modelului de date.

SQLite pe Android: Room și SQLiteOpenHelper

Room — o bibliotecă din Android Jetpack care oferă un strat ORM peste SQLite. Room generează automat interogările SQL din interfețele DAO adnotate, verifică corectitudinea interogărilor în faza de compilare și suportă migrațiile bazei de date la modificarea schemei. Room este modul recomandat de lucru cu SQLite pe Android.

SQLiteOpenHelper — o API de nivel scăzut pentru gestionarea directă a SQLite fără ORM. Clasa gestionează crearea, deschiderea și actualizarea bazei de date. SQLiteOpenHelper este potrivit pentru proiecte cu interogări SQL simple sau când este necesar controlul total asupra logicii SQL fără abstractizarea Room.

Exemplu de entitate și DAO pentru Room

Entitatea în Room este adnotată cu @Entity, iar DAO — cu @Dao. Room traduce metodele adnotate în interogări SQL: @Insert generează INSERT, @Query — SELECT cu SQL-ul specificat. Migrațiile se adaugă prin Migration cu indicarea versiunii vechi și noi a schemei. Room verifică SQL-ul în faza de compilare, ceea ce elimină erorile de sintaxă în producție.

kotlin
@Entity
data class User(
    @PrimaryKey val id: Long,
    val name: String,
    @ColumnInfo(name = "created_at")
    val createdAt: Long
)

@Dao
interface UserDao {
    @Query("SELECT * FROM user ORDER BY name ASC")
    suspend fun getAllUsers(): List<User>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUser(user: User)

    @Query("DELETE FROM user WHERE id = :id")
    suspend fun deleteUser(id: Long)
}

Room generează automat implementarea UserDao_Impl, care conține interogări în timp de execuție către SQLite prin intermediul RoomDatabase intern. Datorită corutinelor (suspend), metodele DAO sunt executate asincron pe firul de fundal, fără a bloca UI. Tipurile de returnare Flow în @Query actualizează automat rezultatul la modificarea tabelului.

SQLite pe iOS: FMDB și GRDB

FMDB — o încapsulare Objective-C peste API-ul C al SQLite, prima bibliotecă populară din punct de vedere istoric pentru iOS. Oferă obiectele FMDatabase și FMResultSet pentru executarea interogărilor și obținerea rezultatelor. FMDB este simplă și minimalistă, dar nu suportă construcții specifice Swift — opționale, Codable, async/await.

GRDB — o bibliotecă modernă Swift pentru lucrul cu SQLite. Oferă o API type-safe, suport pentru Codable, Combine Publishers, async/await, migrații și monitorizarea modificărilor în timp real. GRDB este preferată pentru proiecte noi în Swift datorită integrării complete cu Swift Concurrency și lizibilității mai bune a codului.

Exemplu GRDB în Swift

GRDB definește tabelele prin clase Record conforme cu protocoalele FetchableRecord și TableRecord. Interogările sunt scrise în Swift cu sintaxă type-safe, nu în SQL brut. GRDB suportă de asemenea DatabaseMigrator pentru versionarea schemei și migrații între versiunile aplicației.

swift
struct User: Codable, FetchableRecord, TableRecord {
    var id: Int64
    var name: String
    var createdAt: Date
}

let dbPool = try DatabasePool(path: dbPath)
var migrator = DatabaseMigrator()
migrator.registerMigration("v1") { db in
    try db.create(table: "user") { t in
        t.autoIncrementedPrimaryKey("id")
        t.column("name", .text).notNull()
        t.column("createdAt", .datetime).notNull()
    }
}

let users = try await dbPool.read { db in
    try User.order(Column("name")).fetchAll(db)
}

DatabasePool utilizează modul WAL al SQLite pentru citire concurentă. Mai mulți cititori pot accesa simultan baza de date, în timp ce un singur scriitor actualizează datele prin WAL. GRDB gestionează automat conexiunile și tranzacțiile, asigurând accesul thread-safe la bază din orice fir fără sincronizare manuală.

Optimizarea performanței SQLite

Indecșii — cel mai eficient mod de a accelera interogările SQLite. Un index este creat pe coloanele care participă la WHERE, JOIN și ORDER BY. Pentru un tabel cu 100 000 de înregistrări, căutarea după o coloană indexată durează milisecunde în loc de secunde. Cu toate acestea, indecșii încetinesc INSERT și UPDATE, deci numărul lor trebuie echilibrat cu frecvența scrierii.

Inserarea în lot (batch insert) în cadrul unei singure tranzacții accelerează radical încărcarea în masă a datelor. Inserarea a 1000 de înregistrări una câte una are un supliment de ~1 secundă. Aceleași 1000 de înregistrări într-o singură tranzacție — ~5–10 milisecunde. Diferența se explică prin faptul că fiecare INSERT separat creează o nouă tranzacție cu scriere sincronă pe disc.

Pragme de performanță

PRAGMA — comenzi SQLite pentru configurarea comportamentului bibliotecii. Pragmele cheie de optimizare: PRAGMA synchronous=NORMAL (reduce frecvența fsync), PRAGMA cache_size=-8000 (alocă 8 MB de cache), PRAGMA temp_store=MEMORY (tabele temporare în memorie). Pentru aplicațiile mobile cu volume mari de date, combinația acestor pragme accelerează interogările de 2–3 ori.

O altă optimizare importantă este compilarea prealabilă a interogărilor SQL (prepared statements). Dacă o interogare este executată de mai multe ori (de exemplu, inserarea a 10 000 de rânduri), compilarea SQL o singură dată și apoi utilizarea statement-ului reduce încărcarea CPU cu 30–50%. Room și GRDB stochează automat în cache prepared statements, dar la utilizarea directă a API-ului C al SQLite, compilarea trebuie efectuată manual.

kotlin
class UserRepository(private val db: RoomDatabase) {

    suspend fun insertBatch(users: List<User>) {
        db.withTransaction {
            users.chunked(500).forEach { batch ->
                batch.forEach { user ->
                    insertUser(user)
                }
            }
        }
    }
}

Inserarea în lot cu withTransaction garantează că toate INSERT-urile sunt executate în cadrul unei singure tranzacții. Împărțirea în subloturi (chunked) previne o tranzacție prea mare care ar putea bloca alte fire pentru o perioadă lungă. Pentru sincronizarea în fundal, dimensiunea sublotului de 500 de înregistrări oferă un echilibru optim între viteză și receptivitatea UI.

Întrebări frecvente

Se poate folosi SQLite pe mai multe fire?

Da, SQLite suportă accesul multi-thread în modul WAL. Mai multe fire pot citi simultan datele, dar doar unul poate scrie. Room și GRDB gestionează sincronizarea automat. În modul rollback journal (implicit), baza de date este complet blocată la orice scriere.

Care este dimensiunea maximă a bazei SQLite pe un dispozitiv mobil?

Limita SQLite — 281 TB (maximul teoretic). în practică, dimensiunea bazei este limitată de memoria disponibilă a dispozitivului. Pentru aplicațiile mobile, o dimensiune confortabilă este de până la 1–2 GB. Bazele mai mari de 2 GB încetinesc backup-ul, actualizarea prin App Store și cresc consumul de memorie RAM.

Sunt sigure datele în SQLite?

SQLite nu criptează datele în mod implicit — orice proces cu acces la fișier le poate citi. Pentru criptare, folosiți SQLCipher (extensie cu AES-256), Room cu EncryptedDatabase (Android) sau Encrypted Core Data pe iOS. Criptarea adaugă 5–15% suprasarcină la citirea și scrierea datelor.

Care este diferența dintre SQLite și MySQL?

SQLite este o bibliotecă încorporată (embedded) care nu necesită un proces server. MySQL este un SGBD client-server cu server separat, utilizatori, drepturi de acces și protocol de rețea. SQLite stochează baza de date într-un singur fișier, MySQL — în mai multe fișiere gestionate de server. SQLite este mai simplă și mai ușoară, MySQL mai puternică și mai scalabilă.

Cum să actualizez schema SQLite fără pierderea datelor?

Pentru migrare, folosiți ALTER TABLE (adăugarea coloanelor) sau crearea unui nou tabel cu transferul datelor și ștergerea celui vechi. Room automatizează acest proces prin clasele Migration: specificați startVersion, endVersion și interogările SQL pentru modificarea schemei. GRDB și FMDB oferă DatabaseMigrator similare.

Concluzii

  • SQLite — un SGBD relațional încorporat cu configurare zero, folosit în fiecare aplicație mobilă pe iOS și Android pentru stocarea locală a datelor.
  • Tranzacțiile ACID și modul WAL asigură integritatea datelor și accesul concurent din mai multe fire ale aplicației.
  • Room (Android) și GRDB (iOS) — stratificări moderne peste SQLite care simplifică lucrul cu baza de date prin API type-safe și migrații automate.
  • Arhitectura B-Tree a SQLite asigură căutarea eficientă prin indecși, iar tranzacțiile în lot și prepared statements — performanța ridicată la scriere.
  • SQLite depășește Realm și Core Data prin universalitate (toate platformele), dimensiunea bibliotecii și lipsa dependenței de vendor.
  • Optimizarea prin indecși, modul WAL și setările PRAGMA accelerează interogările de 2–3 ori la sarcinile tipice mobile.
  • Recomandare — folosiți SQLite ca stocare principală pentru datele locale ale aplicației mobile prin Room pe Android și GRDB pe iOS.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și