SQLite i mobil utveckling: vad är det och hur fungerar det

Författare: IT Sectr Publicerad: 2026-03-11 Lästid: 10 min

SQLite är en inbyggd relationsdatabas som fungerar utan en separat serverprocess och lagrar hela databasen i en enda fil på enheten. Tack vare nollkonfiguration, liten biblioteksstorlek och fullt SQL-stöd har SQLite blivit standard för lokal datalagring i mobila applikationer. Enligt SQLite Consortium (2025) används detta DBMS i över 4 miljarder enheter, inklusive varje smartphone på iOS och Android.

Huvudpunkter

  • SQLite — inbyggt relations-DBMS med nollkonfiguration och datalagring i en enda fil.
  • ACID-transaktioner — garanterar dataintegritet även vid strömavbrott eller app-krasch.
  • Datatypning — dynamisk: SQLite kräver inte strikt angivelse av kolumntyp vid tabellskapande.
  • Room — ORM-bibliotek för Android som förenklar arbete med SQLite genom DAO och annoteringar.
  • CoreData kan använda SQLite som Persistent Store på iOS, men lägger till ett lager för objekthantering.

Vad är SQLite?

SQLite är ett bibliotek i programmeringsspråket C som implementerar ett relations-DBMS utan dedikerad server. Det är direkt inbäddat i applikationen, läser och skriver data till en vanlig fil i enhetens filsystem. Biblioteksstorleken är cirka 600 KB, vilket gör SQLite till den lättaste fullt funktionella SQL-databasen.

SQLite stödjer större delen av SQL:1999-standarden, inklusive JOIN, underfrågor, utlösare, vyer, index och fönsterfunktioner. Begränsningarna gäller ALTER TABLE (begränsat stöd) och fullständiga RIGHT/FULL OUTER JOIN. Ändå är SQLites funktionalitet tillräcklig för mobila applikationer i 99% av fallen av lokal lagring.

Enligt Stack Overflow-utvecklarenkäten (2025) är SQLite den mest populära databasen för inbäddade lösningar och rankas trea i popularitet bland alla DBMS efter MySQL och PostgreSQL. Inom mobil utveckling används SQLite i varje applikation — direkt eller genom omslag.

Nyckelegenskaper hos SQLite

Zero-configuration — SQLite kräver ingen installation, konfiguration av behörigheter, skapande av användare eller start av tjänst. Biblioteket kopplas till projektet och databasen skapas genom att anropa en funktion. Detta förenklar driftsättningen radikalt jämfört med klient-server-DBMS som kräver serverinstallation, portkonfiguration och användarkonfiguration.

SQLite-databasfilen är en vanlig plattformsoberoende fil som kan kopieras, analyseras, skickas över nätverket eller återställas från en säkerhetskopia. Filformatet är stabilt på API-nivå: SQLite 3-filer skapade 2004 öppnas med aktuell biblioteksversion, vilket garanterar långsiktig datakompatibilitet.

Hur är SQLite strukturerat: arkitektur och lagring

Arkitekturen i SQLite består av åtta virtuella maskiner: Tokenizer, Parser, Code Generator, VM, B-Tree, Pager, OS Interface och Utilities. En SQL-fråga går igenom Tokenizer (uppdelning i token), Parser (byggande av AST), Code Generator (omvandling till bytekod) och exekveras på den virtuella maskinen som läser datasidor via B-Tree och Pager.

SQLite använder B-Tree för lagring av tabeller och index. Varje tabell lagras som ett separat B-Tree, där bladnoderna innehåller datarader. Index lagras också som B-Tree, men med nycklar i bladen. Pager hanterar inläsning av sidor (standard 4096 byte) från filen till minnet, vilket säkerställer ACID-transaktioner genom journal eller WAL.

Journalföringsmetoder

WAL (Write-Ahead Logging) — rekommenderat läge för mobila applikationer. Ändringar skrivs först till en separat WAL-fil och överförs sedan periodiskt till huvuddatabasen. WAL möjliggör samtidig läsning från databasen (gamla data) och skrivning till den (via WAL), vilket förbättrar prestandan för flertrådade applikationer. Standardjournalen (rollback journal) blockerar läsning under skrivning.

ParameterRollback JournalWAL (Write-Ahead Logging)
Läsning under skrivningBlockerasTillåtet (läser gamla data)
SkrivprestandaMedelHög (sekventiell skrivning till WAL)
DiskförbrukningMindre (endast återställningsjournal)Större (WAL + huvuddatabas)
Återställning vid kraschÅterställning till senaste kontrollpunktenÅterställning från WAL (data går inte förlorade)
RekommendationFör entrådade scenarierFör typiska mobila applikationer

Växling mellan lägena görs med en SQL-fråga: PRAGMA journal_mode=WAL. För mobila applikationer med bakgrundssynkronisering och en UI-tråd som samtidigt läser data ger WAL bättre prestanda och inget blockerande av gränssnittet.

SQLite jämfört med andra databaser i mobil utveckling

SQLite är inte det enda alternativet för lokal datalagring, men det är det mest universella. Realm erbjuder högre hastighet för direkt åtkomst till objekt i minnet, men använder ett eget NoSQL-format och har större biblioteksstorlek. Core Data på iOS är ett ORM-lager ovanpå SQLite som lägger till objekthanthantering och ångring av operationer.

För de flesta applikationer förblir SQLite det optimala valet tack vare förutsägbar prestanda, ingen inlåsningseffekt och tidsprövad stabilitet. Realm och Core Data är motiverade i projekt med komplexa objektdiagram, reaktiva frågor eller synkroniseringskrav mellan enheter.

EgenskapSQLiteRealmCore Data
DatabastypRelations (SQL)NoSQL (objektorienterad)ORM (ovanpå SQLite)
Biblioteksstorlek~600 KB~4 MBInbyggt i Apple SDK
PrestandaMedelHög (objekt i minnet)Medel (ORM-överhead)
PlattformariOS, Android, Web, DesktopiOS, Android, Node.jsiOS, macOS
InlåsningseffektIngen (öppen standard)Medel (eget format)Hög (endast Apple)

Valet mellan SQLite, Realm och Core Data beror på plattform, objektmodellkrav och synkroniseringsstrategi. För plattformsoberoende projekt (KMP, Flutter) förblir SQLite det enda universella valet som fungerar på alla målplattformar utan ändringar i datamodellen.

SQLite på Android: Room och SQLiteOpenHelper

Room — ett bibliotek från Android Jetpack som tillhandahåller ett ORM-lager ovanpå SQLite. Room genererar automatiskt SQL-frågor från annoterade DAO-gränssnitt, kontrollerar frågornas korrekthet vid kompilering och stödjer databasmigreringar vid schemaändringar. Room är det rekommenderade sättet att arbeta med SQLite på Android.

SQLiteOpenHelper — ett lågnivå-API för direkt hantering av SQLite utan ORM. Klassen hanterar skapande, öppnande och uppdatering av databasen. SQLiteOpenHelper är lämpligt för projekt med enkla SQL-frågor eller när full kontroll över SQL-logiken utan Room-abstraktion behövs.

Exempel på entitet och DAO för Room

Entiteten i Room annoteras med @Entity och DAO med @Dao. Room översätter annoterade metoder till SQL-frågor: @Insert genererar INSERT, @Query — SELECT med angiven SQL. Migreringar läggs till via Migration med angivande av gammal och ny schemaversion. Room kontrollerar SQL vid kompilering, vilket eliminerar syntaxfel i produktion.

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 genererar automatiskt implementeringen UserDao_Impl, som innehåller körningsfrågor till SQLite via den interna RoomDatabase. Tack vare korutiner (suspend) körs DAO-metoder asynkront på bakgrundstråden utan att blockera UI. Flow-returtyper i @Query uppdaterar automatiskt resultatet när tabellen ändras.

SQLite på iOS: FMDB och GRDB

FMDB — ett Objective-C-omslag ovanpå SQLites C-API, historiskt det första populära biblioteket för iOS. Det tillhandahåller FMDatabase- och FMResultSet-objekt för att köra frågor och hämta resultat. FMDB är enkelt och minimalistiskt men stödjer inte Swift-specifika konstruktioner — optionals, Codable, async/await.

GRDB — ett modernt Swift-bibliotek för arbete med SQLite. Det erbjuder type-safe API, stöd för Codable, Combine Publishers, async/await, migreringar och realtidsövervakning av ändringar. GRDB föredras för nya Swift-projekt tack vare full integration med Swift Concurrency och bättre kodläsbarhet.

GRDB-exempel i Swift

GRDB definierar tabeller via Record-klasser som följer protokollen FetchableRecord och TableRecord. Frågor skrivs i Swift med type-safe syntax, inte i rå SQL. GRDB stödjer även DatabaseMigrator för versionshantering av schemat och migreringar mellan appversioner.

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 använder SQLites WAL-läge för samtidig läsning. Flera läsare kan samtidigt komma åt databasen medan en skribent uppdaterar data via WAL. GRDB hanterar automatiskt anslutningar och transaktioner, vilket ger trådsäker åtkomst till databasen från vilken tråd som helst utan manuell synkronisering.

Prestandaoptimering av SQLite

Index — det effektivaste sättet att snabba upp SQLite-frågor. Ett index skapas på kolumner som deltar i WHERE, JOIN och ORDER BY. För en tabell med 100 000 poster tar sökning på en indexerad kolumn millisekunder istället för sekunder. Index saktar dock ner INSERT och UPDATE, så deras antal måste balanseras med skrivfrekvensen.

Batchinsättning (batch insert) inom en enda transaktion snabbar upp massiv datainläsning radikalt. Att infoga 1000 poster en och en ger en overhead på cirka 1 sekund. Samma 1000 poster i en transaktion — cirka 5–10 millisekunder. Skillnaden förklaras av att varje enskild INSERT skapar en ny transaktion med synkron skrivning till disk.

Prestanda-PRAGMA

PRAGMA — SQLite-kommandon för att konfigurera bibliotekets beteende. Viktiga optimerings-PRAGMA: PRAGMA synchronous=NORMAL (minskar fsync-frekvens), PRAGMA cache_size=-8000 (allokerar 8 MB cache), PRAGMA temp_store=MEMORY (temporära tabeller i minnet). För mobila applikationer med stora datavolymer snabbar kombinationen av dessa PRAGMA upp frågor 2–3 gånger.

En annan viktig optimering är förkompilering av SQL-frågor (prepared statements). Om en fråga körs upprepade gånger (t.ex. insättning av 10 000 rader) minskar en engångskompilering av SQL och sedan användning av statement CPU-belastningen med 30–50%. Room och GRDB cachar automatiskt prepared statements, men vid direkt användning av SQLite C-API måste kompileringen göras manuellt.

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)
                }
            }
        }
    }
}

Batchinsättning med withTransaction garanterar att alla INSERT körs inom en enda transaktion. Uppdelning i underbatchar (chunked) förhindrar en alltför stor transaktion som skulle kunna blockera andra trådar under längre tid. För bakgrundssynkronisering ger en underbatchstorlek på 500 poster optimal balans mellan hastighet och UI-svarstid.

Vanliga frågor

Kan SQLite användas på flera trådar?

Ja, SQLite stödjer flertrådad åtkomst i WAL-läge. Flera trådar kan samtidigt läsa data, men endast en kan skriva. Room och GRDB hanterar synkroniseringen automatiskt. I rollback journal-läge (standard) blockeras databasen helt vid all skrivning.

Vad är den maximala storleken på en SQLite-databas på en mobil enhet?

Begränsningen för SQLite är 281 TB (teoretiskt maximum). I praktiken begränsas databasstorleken av enhetens tillgängliga minne. För mobila applikationer är en bekväm storlek upp till 1–2 GB. Databaser större än 2 GB saktar ner säkerhetskopiering, uppdatering via App Store och ökar RAM-förbrukningen.

Är data i SQLite säkra?

SQLite krypterar inte data som standard — alla processer med åtkomst till filen kan läsa dem. För kryptering, använd SQLCipher (tillägg med AES-256), Room med EncryptedDatabase (Android) eller Encrypted Core Data på iOS. Kryptering lägger till 5–15% overhead vid läsning och skrivning av data.

Vad är skillnaden mellan SQLite och MySQL?

SQLite är ett inbäddat (embedded) bibliotek som inte kräver en serverprocess. MySQL är ett klient-server-DBMS med separat server, användare, åtkomsträttigheter och nätverksprotokoll. SQLite lagrar databasen i en enda fil, MySQL i flera filer som hanteras av servern. SQLite är enklare och lättare, MySQL är kraftfullare och mer skalbart.

Hur uppdaterar man SQLite-schemat utan att förlora data?

För migrering, använd ALTER TABLE (lägg till kolumner) eller skapa en ny tabell med dataöverföring och ta bort den gamla. Room automatiserar denna process genom Migration-klasser: ange startVersion, endVersion och SQL-frågor för att ändra schemat. GRDB och FMDB tillhandahåller liknande DatabaseMigrator.

Sammanfattning

  • SQLite — inbyggt relations-DBMS med nollkonfiguration, används i varje mobil applikation på iOS och Android för lokal datalagring.
  • ACID-transaktioner och WAL-läge säkerställer dataintegritet och samtidig åtkomst från flera applikationstrådar.
  • Room (Android) och GRDB (iOS) — moderna omslag för SQLite som förenklar databasarbete genom type-safe API och automatiska migreringar.
  • SQLites B-Tree-arkitektur säkerställer effektiv sökning via index, och batchtransaktioner och prepared statements säkerställer hög skrivprestanda.
  • SQLite överträffar Realm och Core Data i universalitet (alla plattformar), biblioteksstorlek och avsaknad av inlåsningseffekt.
  • Optimering via index, WAL-läge och PRAGMA-inställningar snabbar upp frågor 2–3 gånger vid typisk mobil belastning.
  • Rekommendation — använd SQLite som primär lagring för lokal data i mobila applikationer via Room på Android och GRDB på iOS.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också