SQLite je vestavěná relační databáze, která funguje bez samostatného serverového procesu a ukládá celou databázi do jednoho souboru na zařízení. Díky nulové konfiguraci, malé velikosti knihovny a plné podpoře SQL se SQLite stalo standardem pro lokální ukládání dat v mobilních aplikacích. Podle údajů SQLite Consortium (2025) je tato ŘÍP používána ve více než 4 miliardách zařízení, včetně každého chytrého telefonu na iOS a Androidu.
Hlavní body
SQLite je knihovna v jazyce C, která implementuje relační ŘÍP bez vyhrazeného serveru. Je přímo vestavěna do aplikace, čte a zapisuje data do běžného souboru v souborovém systému zařízení. Velikost knihovny je přibližně 600 KB, což činí SQLite nejlehčí plně funkční SQL databází.
SQLite podporuje většinu standardu SQL:1999, včetně JOIN, poddotazů, triggerů, pohledů, indexů a okenních funkcí. Omezení se týkají ALTER TABLE (omezená podpora) a úplného RIGHT/FULL OUTER JOIN. Nicméně pro mobilní aplikace je funkcionalita SQLite dostačující v 99 % případů lokálního ukládání.
Podle průzkumu vývojářů Stack Overflow (2025) je SQLite nejoblíbenější databází pro vestavěná řešení a zaujímá třetí místo v oblíbenosti mezi všemi ŘÍP po MySQL a PostgreSQL. V mobilním vývoji se SQLite používá v každé aplikaci — přímo nebo prostřednictvím obalů.
Zero-configuration — SQLite nevyžaduje instalaci, nastavení oprávnění, vytváření uživatelů nebo spuštění služby. Knihovna se připojí k projektu a databáze se vytvoří zavoláním jedné funkce. To radikálně zjednodušuje nasazení ve srovnání s ŘÍP klient-server, která vyžadují instalaci serveru, konfiguraci portů a konfiguraci uživatelů.
Soubor databáze SQLite je běžný multiplatformní soubor, který lze zkopírovat, analyzovat, odeslat po síti nebo obnovit ze zálohy. Formát souboru je na úrovni API stabilní: soubory SQLite 3 vytvořené v roce 2004 se otevírají aktuální verzí knihovny, což zaručuje dlouhodobou kompatibilitu dat.
Architektura SQLite se skládá z osmi virtuálních strojů: Tokenizer, Parser, Code Generator, VM, B-Tree, Pager, OS Interface a Utilities. SQL dotaz prochází Tokenizerem (rozdělení na tokeny), Parserem (stavba AST), Code Generatorem (převod na bajtový kód) a je proveden na virtuálním stroji, který čte stránky dat prostřednictvím B-Tree a Pageru.
SQLite používá B-Tree pro ukládání tabulek a indexů. Každá tabulka je uložena jako samostatné B-Tree, kde listové uzly obsahují řádky dat. Indexy jsou také uloženy jako B-Tree, ale s klíči v listech. Pager řídí načítání stránek (ve výchozím nastavení 4096 bajtů) ze souboru do paměti, čímž zajišťuje ACID transakce prostřednictvím protokolu nebo WAL.
WAL (Write-Ahead Logging) — doporučený režim pro mobilní aplikace. Změny se nejprve zapíší do samostatného WAL souboru a poté se periodicky přenášejí do hlavní databáze. WAL umožňuje současné čtení z databáze (stará data) a zápis do ní (prostřednictvím WAL), což zvyšuje výkon vícevláknových aplikací. Standardní protokol (rollback journal) blokuje čtení během zápisu.
| Parametr | Rollback Journal | WAL (Write-Ahead Logging) |
|---|---|---|
| Čtení během zápisu | Blokováno | Povoleno (čte stará data) |
| Výkon zápisu | Střední | Vysoký (sekvenční zápis do WAL) |
| Spotřeba disku | Menší (pouze protokol vrácení) | Větší (WAL + hlavní databáze) |
| Obnova po selhání | Vrácení k poslednímu kontrolnímu bodu | Obnova z WAL (data se neztrácejí) |
| Doporučení | Pro jednovláknové scénáře | Pro typické mobilní aplikace |
Přepínání mezi režimy se provádí jedním SQL dotazem: PRAGMA journal_mode=WAL. Pro mobilní aplikace s backendovou synchronizací a vláknem UI, které současně čte data, poskytuje WAL lepší výkon a žádné blokování rozhraní.
SQLite není jedinou možností pro lokální ukládání dat, ale je nejuniverzálnější. Realm nabízí vyšší rychlost přímého přístupu k objektům v paměti, ale používá vlastní formát NoSQL a má větší velikost knihovny. Core Data na iOS je ORM vrstva nad SQLite, která přidává správu grafu objektů a vrácení operací.
Pro většinu aplikací zůstává SQLite optimální volbou díky předvídatelnému výkonu, žádné závislosti na dodavateli a časem prověřené stabilitě. Realm a Core Data jsou oprávněné v projektech se složitými grafy objektů, reaktivními dotazy nebo požadavky na synchronizaci mezi zařízeními.
| Vlastnost | SQLite | Realm | Core Data |
|---|---|---|---|
| Typ databáze | Relační (SQL) | NoSQL (objektová) | ORM (nad SQLite) |
| Velikost knihovny | ~600 KB | ~4 MB | Vestavěno v Apple SDK |
| Výkon | Střední | Vysoký (objekty v paměti) | Střední (režie ORM) |
| Platformy | iOS, Android, Web, Desktop | iOS, Android, Node.js | iOS, macOS |
| Závislost na dodavateli | Žádná (otevřený standard) | Střední (vlastní formát) | Vysoká (pouze Apple) |
Výběr mezi SQLite, Realm a Core Data závisí na platformě, požadavcích na objektový model a strategii synchronizace. Pro multiplatformní projekty (KMP, Flutter) zůstává SQLite jedinou univerzální volbou, která funguje na všech cílových platformách bez změn modelu dat.
Room — knihovna z Android Jetpack, která poskytuje ORM vrstvu nad SQLite. Room automaticky generuje SQL dotazy z anotovaných DAO rozhraní, kontroluje správnost dotazů při kompilaci a podporuje migrace databáze při změně schématu. Room je doporučený způsob práce s SQLite na Androidu.
SQLiteOpenHelper — nízkoúrovňové API pro přímou správu SQLite bez ORM. Třída řídí vytváření, otevírání a aktualizaci databáze. SQLiteOpenHelper je vhodný pro projekty s jednoduchými SQL dotazy nebo když je potřeba úplná kontrola nad SQL logikou bez abstrakce Room.
Entita v Room je anotována @Entity a DAO @Dao. Room převádí anotované metody na SQL dotazy: @Insert generuje INSERT, @Query — SELECT s uvedeným SQL. Migrace se přidávají prostřednictvím Migration s uvedením staré a nové verze schématu. Room kontroluje SQL při kompilaci, což eliminuje syntaktické chyby v produkci.
@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 automaticky generuje implementaci UserDao_Impl, která obsahuje runtime dotazy na SQLite prostřednictvím interního RoomDatabase. Díky korutinám (suspend) jsou DAO metody prováděny asynchronně na backendovém vlákně, aniž by blokovaly UI. Návratové typy Flow v @Query automaticky aktualizují výsledek při změně tabulky.
FMDB — Objective-C obal nad C API SQLite, historicky první populární knihovna pro iOS. Poskytuje objekty FMDatabase a FMResultSet pro provádění dotazů a získávání výsledků. FMDB je jednoduchá a minimalistická, ale nepodporuje Swift-specifické konstrukce — optionals, Codable, async/await.
GRDB — moderní Swift knihovna pro práci s SQLite. Poskytuje type-safe API, podporu Codable, Combine Publishers, async/await, migrace a sledování změn v reálném čase. GRDB je preferována pro nové projekty ve Swiftu díky plné integraci se Swift Concurrency a lepší čitelnosti kódu.
GRDB definuje tabulky pomocí Record tříd, které vyhovují protokolům FetchableRecord a TableRecord. Dotazy se píší ve Swiftu s type-safe syntaxí, nikoli v syrovém SQL. GRDB také podporuje DatabaseMigrator pro verzování schématu a migrace mezi verzemi aplikace.
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 používá WAL režim SQLite pro souběžné čtení. Více čtenářů může současně přistupovat k databázi, zatímco jeden zapisovatel aktualizuje data prostřednictvím WAL. GRDB automaticky spravuje připojení a transakce, čímž poskytuje thread-safe přístup k databázi z libovolného vlákna bez ruční synchronizace.
Indexy — nejúčinnější způsob zrychlení SQLite dotazů. Index je vytvořen na sloupcích, které se účastní WHERE, JOIN a ORDER BY. Pro tabulku se 100 000 záznamy trvá vyhledávání podle indexovaného sloupce milisekundy místo sekund. Indexy ale zpomalují INSERT a UPDATE, proto musí být jejich počet vyvážen s frekvencí zápisu.
Dávkový vkládání (batch insert) v rámci jedné transakce radikálně zrychluje hromadné načítání dat. Vložení 1000 záznamů jeden po druhém má režii přibližně 1 sekundu. Stejných 1000 záznamů v jedné transakci — přibližně 5–10 milisekund. Rozdíl je způsoben tím, že každý samostatný INSERT vytváří novou transakci se synchronním zápisem na disk.
PRAGMA — příkazy SQLite pro konfiguraci chování knihovny. Klíčové optimalizační PRAGMA: PRAGMA synchronous=NORMAL (snižuje frekvenci fsync), PRAGMA cache_size=-8000 (alokuje 8 MB cache), PRAGMA temp_store=MEMORY (dočasné tabulky v paměti). Pro mobilní aplikace s velkými objemy dat kombinace těchto PRAGMA zrychluje dotazy 2–3krát.
Další důležitou optimalizací je předkompilace SQL dotazů (prepared statements). Pokud se dotaz provádí opakovaně (například vkládání 10 000 řádků), jednorázová kompilace SQL a následné použití statementu snižuje zátěž CPU o 30–50%. Room a GRDB automaticky kešují prepared statements, ale při přímém použití C API SQLite je třeba kompilaci provést ručně.
class UserRepository(private val db: RoomDatabase) {
suspend fun insertBatch(users: List<User>) {
db.withTransaction {
users.chunked(500).forEach { batch ->
batch.forEach { user ->
insertUser(user)
}
}
}
}
}
Dávkový vkládání s withTransaction zaručuje, že všechny INSERT jsou provedeny v rámci jedné transakce. Rozdělení na poddávky (chunked) zabraňuje příliš velké transakci, která by mohla blokovat ostatní vlákna na delší dobu. Pro backendovou synchronizaci poskytuje velikost poddávky 500 záznamů optimální rovnováhu mezi rychlostí a odezvou UI.
Často kladené otázky
Ano, SQLite podporuje vícevláknový přístup v režimu WAL. Více vláken může současně číst data, ale zapisovat může pouze jeden. Room a GRDB řídí synchronizaci automaticky. V režimu rollback journal (výchozí) je databáze při jakémkoli zápisu zcela blokována.
Omezení SQLite — 281 TB (teoretické maximum). V praxi je velikost databáze omezena dostupnou pamětí zařízení. Pro mobilní aplikace je pohodlná velikost do 1–2 GB. Databáze větší než 2 GB zpomalují zálohování, aktualizaci prostřednictvím App Store a zvyšují spotřebu RAM.
SQLite data ve výchozím nastavení nešifruje — jakýkoli proces s přístupem k souboru je může číst. Pro šifrování použijte SQLCipher (rozšíření s AES-256), Room s EncryptedDatabase (Android) nebo Encrypted Core Data na iOS. Šifrování přidává 5–15% režii při čtení a zápisu dat.
SQLite je vestavěná (embedded) knihovna, která nevyžaduje serverový proces. MySQL je ŘÍP klient-server s odděleným serverem, uživateli, přístupovými právy a síťovým protokolem. SQLite ukládá databázi do jednoho souboru, MySQL do několika souborů spravovaných serverem. SQLite je jednodušší a lehčí, MySQL je výkonnější a škálovatelnější.
Pro migraci použijte ALTER TABLE (přidání sloupců) nebo vytvoření nové tabulky s přenosem dat a odstraněním staré. Room tento proces automatizuje pomocí tříd Migration: zadejte startVersion, endVersion a SQL dotazy pro změnu schématu. GRDB a FMDB poskytují podobný DatabaseMigrator.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také