SQLite একটি এমবেডেড রিলেশনাল ডেটাবেস যা আলাদা সার্ভার প্রক্রিয়া ছাড়াই কাজ করে এবং পুরো ডেটাবেস ডিভাইসের একটি ফাইলে সংরক্ষণ করে। শূন্য কনফিগারেশন, ছোট লাইব্রেরি আকার এবং পূর্ণ SQL সমর্থনের জন্য, SQLite মোবাইল অ্যাপ্লিকেশনে স্থানীয় ডেটা স্টোরেজের মানদণ্ডে পরিণত হয়েছে। SQLite কনসোর্টিয়াম (2025) অনুসারে, এই DBMS 4 বিলিয়নেরও বেশি ডিভাইসে ব্যবহৃত হয়, যার মধ্যে iOS এবং Android-এর প্রতিটি স্মার্টফোন অন্তর্ভুক্ত।
মূল পয়েন্ট
SQLite একটি C ভাষার লাইব্রেরি যা ডেডিকেটেড সার্ভার ছাড়াই একটি রিলেশনাল DBMS বাস্তবায়ন করে। এটি সরাসরি অ্যাপ্লিকেশনে এমবেড হয়, ডিভাইসের ফাইল সিস্টেমে একটি সাধারণ ফাইলে ডেটা পড়ে এবং লেখে। লাইব্রেরির আকার প্রায় 600 KB, যা SQLite-কে সবচেয়ে হালকা পূর্ণ-বৈশিষ্ট্যসম্পন্ন SQL ডেটাবেসে পরিণত করেছে।
SQLite SQL:1999 মানের বেশিরভাগ অংশ সমর্থন করে, যার মধ্যে JOIN, সাবকোয়েরি, ট্রিগার, ভিউ, ইনডেক্স এবং উইন্ডো ফাংশন অন্তর্ভুক্ত। সীমাবদ্ধতাগুলি ALTER TABLE (সীমিত সমর্থন) এবং পূর্ণ RIGHT/FULL OUTER JOIN-এর সাথে সম্পর্কিত। তবুও, মোবাইল অ্যাপ্লিকেশনের জন্য, SQLite-এর কার্যকারিতা 99% স্থানীয় স্টোরেজ ক্ষেত্রে যথেষ্ট।
Stack Overflow ডেভেলপার জরিপ (2025) অনুসারে, SQLite এমবেডেড সমাধানের জন্য সবচেয়ে জনপ্রিয় ডেটাবেস এবং MySQL ও PostgreSQL-এর পরে সমস্ত DBMS-এর মধ্যে জনপ্রিয়তায় তৃতীয় স্থানে রয়েছে। মোবাইল ডেভেলপমেন্টে, SQLite প্রতিটি অ্যাপ্লিকেশনে ব্যবহৃত হয় — সরাসরি অথবা র্যাপারের মাধ্যমে।
শূন্য কনফিগারেশন — SQLite-এর ইনস্টলেশন, অনুমতি সেটআপ, ব্যবহারকারী তৈরি বা সার্ভিস শুরু করার প্রয়োজন নেই। লাইব্রেরি প্রকল্পের সাথে সংযুক্ত হয় এবং একটি ফাংশন কল করে ডেটাবেস তৈরি করা হয়। এটি ক্লায়েন্ট-সার্ভার DBMS-এর তুলনায় ডিপ্লয়মেন্টকে মৌলিকভাবে সহজ করে, যেখানে সার্ভার ইনস্টলেশন, পোর্ট কনফিগারেশন এবং ব্যবহারকারী সেটআপ প্রয়োজন।
SQLite ডেটাবেস ফাইলটি একটি সাধারণ ক্রস-প্ল্যাটফর্ম ফাইল যা কপি, বিশ্লেষণ, নেটওয়ার্কের মাধ্যমে পাঠানো বা ব্যাকআপ থেকে পুনরুদ্ধার করা যায়। ফাইল ফরম্যাট API স্তরে স্থিতিশীল: 2004 সালে তৈরি SQLite 3 ফাইলগুলি লাইব্রেরির বর্তমান সংস্করণ দিয়ে খোলে, যা দীর্ঘমেয়াদী ডেটা সামঞ্জস্য নিশ্চিত করে।
SQLite-এর আর্কিটেকচার আটটি ভার্চুয়াল মেশিন নিয়ে গঠিত: Tokenizer, Parser, Code Generator, VM, B-Tree, Pager, OS Interface এবং Utilities। একটি SQL কোয়েরি Tokenizer (টোকেনে বিভাজন), Parser (AST নির্মাণ), Code Generator (বাইটকোডে রূপান্তর) এর মধ্য দিয়ে যায় এবং ভার্চুয়াল মেশিনে নির্বাহিত হয়, যা B-Tree এবং Pager-এর মাধ্যমে ডেটা পৃষ্ঠা পড়ে।
SQLite টেবিল এবং ইনডেক্স সংরক্ষণের জন্য B-Tree ব্যবহার করে। প্রতিটি টেবিল একটি পৃথক B-Tree হিসেবে সংরক্ষিত হয়, যেখানে লিফ নোডে ডেটা সারি থাকে। ইনডেক্সগুলিও B-Tree হিসেবে সংরক্ষিত হয় তবে লিভসে কী সহ। Pager ফাইল থেকে মেমরিতে পৃষ্ঠা (ডিফল্ট 4096 বাইট) লোড করার ব্যবস্থাপনা করে, জার্নাল বা WAL-এর মাধ্যমে ACID লেনদেন প্রদান করে।
WAL (Write-Ahead Logging) মোবাইল অ্যাপ্লিকেশনের জন্য প্রস্তাবিত মোড। পরিবর্তনগুলি প্রথমে একটি আলাদা WAL ফাইলে লেখা হয় এবং তারপর পর্যায়ক্রমে মূল ডেটাবেসে স্থানান্তরিত হয়। WAL ডেটাবেস থেকে একসাথে পড়ার (পুরানো ডেটা) এবং লেখার (WAL-এর মাধ্যমে) অনুমতি দেয়, যা মাল্টিথ্রেডেড অ্যাপ্লিকেশনের কর্মক্ষমতা উন্নত করে। স্ট্যান্ডার্ড জার্নাল (রোলব্যাক জার্নাল) লেখার সময় পড়া ব্লক করে।
| প্যারামিটার | রোলব্যাক জার্নাল | WAL (Write-Ahead Logging) |
|---|---|---|
| লেখার সময় পড়া | ব্লকড | অনুমোদিত (পুরানো ডেটা পড়ে) |
| লেখার কর্মক্ষমতা | মধ্যম | উচ্চ (WAL-এ অনুক্রমিক লেখা) |
| ডিস্ক খরচ | কম (শুধু রোলব্যাক জার্নাল) | বেশি (WAL + মূল ডেটাবেস) |
| ক্র্যাশ পুনরুদ্ধার | শেষ চেকপয়েন্টে রোলব্যাক | WAL থেকে পুনরুদ্ধার (ডেটা ক্ষতি নেই) |
| সুপারিশ | একক-থ্রেডেড পরিস্থিতির জন্য | সাধারণ মোবাইল অ্যাপ্লিকেশনের জন্য |
মোডের মধ্যে সুইচিং একটি SQL কোয়েরি দিয়ে করা হয়: PRAGMA journal_mode=WAL. ব্যাকগ্রাউন্ড সিঙ্ক্রোনাইজেশন এবং একসাথে ডেটা পড়া UI থ্রেডযুক্ত মোবাইল অ্যাপ্লিকেশনের জন্য, WAL ভাল কর্মক্ষমতা এবং ইন্টারফেস লকআপের অনুপস্থিতি নিশ্চিত করে।
SQLite স্থানীয় ডেটা স্টোরেজের একমাত্র বিকল্প নয়, তবে সবচেয়ে বহুমুখী। Realm মেমরিতে অবজেক্টে সরাসরি অ্যাক্সেসের উচ্চ গতি প্রদান করে তবে নিজস্ব NoSQL ফরম্যাট ব্যবহার করে এবং এর লাইব্রেরির আকার বড়। iOS-এ Core Data হল SQLite-এর উপরে একটি ORM স্তর যা অবজেক্ট গ্রাফ ম্যানেজমেন্ট এবং অপারেশন আনডু যোগ করে।
বেশিরভাগ অ্যাপ্লিকেশনের জন্য, SQLite পূর্বানুমানযোগ্য কর্মক্ষমতা, শূন্য ভেন্ডর লক-ইন এবং সময়-পরীক্ষিত স্থিতিশীলতার কারণে সর্বোত্তম পছন্দ হিসেবে রয়ে গেছে। জটিল অবজেক্ট গ্রাফ, রিঅ্যাক্টিভ কোয়েরি বা ক্রস-ডিভাইস সিঙ্ক্রোনাইজেশন প্রয়োজন এমন প্রকল্পে Realm এবং Core Data যুক্তিযুক্ত।
| বৈশিষ্ট্য | SQLite | Realm | Core Data |
|---|---|---|---|
| ডেটাবেসের ধরন | রিলেশনাল (SQL) | NoSQL (অবজেক্ট-ভিত্তিক) | ORM (SQLite-এর উপরে) |
| লাইব্রেরির আকার | ~600 KB | ~4 MB | Apple SDK-তে নির্মিত |
| কর্মক্ষমতা | মধ্যম | উচ্চ (মেমরিতে অবজেক্ট) | মধ্যম (ORM ওভারহেড) |
| প্ল্যাটফর্ম | iOS, Android, ওয়েব, ডেস্কটপ | iOS, Android, Node.js | iOS, macOS |
| ভেন্ডর লক-ইন | নেই (ওপেন স্ট্যান্ডার্ড) | মধ্যম (মালিকানা ফরম্যাট) | উচ্চ (শুধু Apple) |
SQLite, Realm এবং Core Data-এর মধ্যে পছন্দ প্ল্যাটফর্ম, অবজেক্ট মডেল প্রয়োজনীয়তা এবং সিঙ্ক্রোনাইজেশন কৌশলের উপর নির্ভর করে। ক্রস-প্ল্যাটফর্ম প্রকল্পের (KMP, Flutter) জন্য, SQLite একমাত্র সার্বজনীন পছন্দ হিসেবে রয়ে গেছে যা ডেটা মডেলে পরিবর্তন ছাড়াই সমস্ত টার্গেট প্ল্যাটফর্মে কাজ করে।
Room Android Jetpack-এর একটি লাইব্রেরি যা SQLite-এর উপরে ORM স্তর প্রদান করে। Room অ্যানোটেটেড DAO ইন্টারফেস থেকে স্বয়ংক্রিয়ভাবে SQL কোয়েরি তৈরি করে, কম্পাইল টাইমে কোয়েরি সঠিকতা যাচাই করে এবং স্কিমা পরিবর্তনের সময় ডেটাবেস মাইগ্রেশন সমর্থন করে। Android-এ SQLite-এর সাথে কাজ করার প্রস্তাবিত উপায় হল Room।
SQLiteOpenHelper ORM ছাড়া সরাসরি SQLite ব্যবস্থাপনার জন্য নিম্ন-স্তরের API। ক্লাস ডেটাবেস তৈরি, খোলা এবং আপগ্রেড করার ব্যবস্থাপনা করে। SQLiteOpenHelper সহজ SQL কোয়েরি বা যখন Room অ্যাবস্ট্রাকশন ছাড়া SQL লজিকের উপর পূর্ণ নিয়ন্ত্রণ প্রয়োজন, এমন প্রকল্পের জন্য উপযুক্ত।
Room-এ একটি এন্টিটি @Entity দিয়ে এবং DAO @Dao দিয়ে অ্যানোটেট করা হয়। Room অ্যানোটেটেড পদ্ধতিগুলিকে SQL কোয়েরিতে অনুবাদ করে: @Insert INSERT তৈরি করে, @Query নির্দিষ্ট SQL সহ SELECT তৈরি করে। মাইগ্রেশন পুরানো এবং নতুন স্কিমা সংস্করণ উল্লেখ করে Migration ক্লাসের মাধ্যমে যোগ করা হয়। Room কম্পাইল টাইমে SQL যাচাই করে, যা প্রোডাকশনে সিনট্যাক্স ত্রুটি দূর করে।
@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 স্বয়ংক্রিয়ভাবে UserDao_Impl বাস্তবায়ন তৈরি করে, যাতে অভ্যন্তরীণ RoomDatabase-এর মাধ্যমে রানটাইম SQLite কোয়েরি থাকে। করুটিন (suspend) এর জন্য, DAO পদ্ধতিগুলি ব্যাকগ্রাউন্ড থ্রেডে অ্যাসিঙ্ক্রোনাসভাবে নির্বাহিত হয়, UI ব্লক না করে। @Query-তে Flow রিটার্ন টাইপ টেবিল পরিবর্তনের সময় স্বয়ংক্রিয়ভাবে ফলাফল আপডেট করে।
FMDB SQLite C API-এর উপর একটি Objective-C র্যাপার, ঐতিহাসিকভাবে iOS-এর জন্য প্রথম জনপ্রিয় লাইব্রেরি। এটি কোয়েরি নির্বাহ এবং ফলাফল পাওয়ার জন্য FMDatabase এবং FMResultSet অবজেক্ট প্রদান করে। FMDB সহজ এবং ন্যূনতম, কিন্তু Swift-নির্দিষ্ট কনস্ট্রাক্ট — অপশনাল, Codable, async/await সমর্থন করে না।
GRDB SQLite-এর সাথে কাজ করার জন্য একটি আধুনিক Swift লাইব্রেরি। এটি type-safe API, Codable সমর্থন, Combine Publishers, async/await, মাইগ্রেশন এবং রিয়েল-টাইম পরিবর্তন পর্যবেক্ষণ প্রদান করে। GRDB Swift Concurrency-এর সাথে সম্পূর্ণ একীকরণ এবং ভাল কোড পঠনযোগ্যতার কারণে নতুন Swift প্রকল্পের জন্য পছন্দ করা হয়।
GRDB FetchableRecord এবং TableRecord প্রোটোকল মেনে চলা Record ক্লাসের মাধ্যমে টেবিল সংজ্ঞায়িত করে। কোয়েরি raw SQL-এর পরিবর্তে type-safe সিনট্যাক্স সহ Swift-এ লেখা হয়। GRDB স্কিমা ভার্সনিং এবং অ্যাপ সংস্করণের মধ্যে মাইগ্রেশনের জন্য DatabaseMigrator-ও সমর্থন করে।
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 সমবর্তী পড়ার জন্য SQLite-এর WAL মোড ব্যবহার করে। একাধিক পাঠক একসাথে ডেটাবেস অ্যাক্সেস করতে পারে যখন একজন একক লেখক WAL-এর মাধ্যমে ডেটা আপডেট করে। GRDB স্বয়ংক্রিয়ভাবে সংযোগ এবং লেনদেন পরিচালনা করে, ম্যানুয়াল সিঙ্ক্রোনাইজেশন ছাড়াই যেকোনো থ্রেড থেকে থ্রেড-নিরাপদ ডেটাবেস অ্যাক্সেস প্রদান করে।
ইনডেক্স SQLite কোয়েরি দ্রুত করার সবচেয়ে কার্যকর উপায়। WHERE, JOIN এবং ORDER BY-তে ব্যবহৃত কলামে ইনডেক্স তৈরি করা হয়। 100000 রেকর্ডের টেবিলের জন্য, ইনডেক্স করা কলামে অনুসন্ধান সেকেন্ডের পরিবর্তে মিলিসেকেন্ডে হয়। তবে, ইনডেক্স INSERT এবং UPDATE ধীর করে, তাই তাদের সংখ্যা লেখার ফ্রিকোয়েন্সির সাথে ভারসাম্যপূর্ণ হওয়া উচিত।
একটি লেনদেনের মধ্যে ব্যাচ ইনসার্ট গণ ডেটা লোডিংকে মৌলিকভাবে দ্রুত করে। একে একে 1000 রেকর্ড ঢোকাতে ~1 সেকেন্ডের ওভারহেড হয়। একই লেনদেনে 1000 রেকর্ড ~5-10 মিলিসেকেন্ড নেয়। পার্থক্যটি এইভাবে ব্যাখ্যা করা হয় যে প্রতিটি পৃথক INSERT সিঙ্ক্রোনাস ডিস্ক লেখার সাথে একটি নতুন লেনদেন তৈরি করে।
PRAGMA লাইব্রেরির আচরণ কনফিগার করার জন্য SQLite কমান্ড। মূল অপ্টিমাইজেশন প্রাগমা: PRAGMA synchronous=NORMAL (fsync ফ্রিকোয়েন্সি কমায়), PRAGMA cache_size=-8000 (8 MB ক্যাশে বরাদ্দ করে), PRAGMA temp_store=MEMORY (মেমরিতে অস্থায়ী টেবিল)। বড় ডেটা ভলিউম সহ মোবাইল অ্যাপ্লিকেশনের জন্য, এই প্রাগমাগুলির সংমিশ্রণ কোয়েরি 2-3 গুণ দ্রুত করে।
আরেকটি গুরুত্বপূর্ণ অপ্টিমাইজেশন হল SQL কোয়েরির প্রি-কম্পাইলেশন (prepared statements)। যদি একটি কোয়েরি বারবার নির্বাহিত হয় (যেমন, 10000 সারি ঢোকানো), SQL একবার কম্পাইল করা এবং তারপর স্টেটমেন্ট পুনরায় ব্যবহার করা CPU লোড 30-50% কমায়। Room এবং GRDB স্বয়ংক্রিয়ভাবে prepared statements ক্যাশ করে, কিন্তু সরাসরি SQLite C API ব্যবহার করার সময়, কম্পাইলেশন ম্যানুয়ালি করতে হবে।
class UserRepository(private val db: RoomDatabase) {
suspend fun insertBatch(users: List<User>) {
db.withTransaction {
users.chunked(500).forEach { batch ->
batch.forEach { user ->
insertUser(user)
}
}
}
}
}
withTransaction সহ ব্যাচ ইনসার্ট নিশ্চিত করে যে সমস্ত INSERT অপারেশন একটি লেনদেনের মধ্যে নির্বাহিত হয়। চাঙ্কিং (chunked) উপ-ব্যাচে বিভাজন একটি লেনদেনকে খুব বড় হতে বাধা দেয়, যা অন্য থ্রেডকে দীর্ঘ সময়ের জন্য ব্লক করতে পারে। ব্যাকগ্রাউন্ড সিঙ্ক্রোনাইজেশনের জন্য, 500 রেকর্ডের উপ-ব্যাচ আকার গতি এবং UI প্রতিক্রিয়াশীলতার সর্বোত্তম ভারসাম্য প্রদান করে।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
হ্যাঁ, SQLite WAL মোডে মাল্টি-থ্রেডেড অ্যাক্সেস সমর্থন করে। একাধিক থ্রেড একসাথে ডেটা পড়তে পারে, কিন্তু শুধুমাত্র একটি লিখতে পারে। Room এবং GRDB স্বয়ংক্রিয়ভাবে সিঙ্ক্রোনাইজেশন পরিচালনা করে। রোলব্যাক জার্নাল মোডে (ডিফল্ট), যেকোনো লেখার অপারেশনের সময় ডেটাবেস সম্পূর্ণরূপে লক হয়ে যায়।
SQLite-এর সীমা 281 TB (তাত্ত্বিক সর্বোচ্চ)। বাস্তবে, ডেটাবেসের আকার ডিভাইসের উপলব্ধ মেমরি দ্বারা সীমিত। মোবাইল অ্যাপ্লিকেশনের জন্য, আরামদায়ক আকার 1-2 GB পর্যন্ত। 2 GB-এর বড় ডেটাবেস ব্যাকআপ, App Store আপডেট ধীর করে এবং RAM খরচ বাড়ায়।
SQLite ডিফল্টভাবে ডেটা এনক্রিপ্ট করে না — ফাইলে অ্যাক্সেস আছে এমন যেকোনো প্রক্রিয়া এটি পড়তে পারে। এনক্রিপশনের জন্য, SQLCipher (AES-256 সহ এক্সটেনশন), EncryptedDatabase (Android) সহ Room, বা iOS-এ Encrypted Core Data ব্যবহার করুন। এনক্রিপশন ডেটা পড়া এবং লেখার অপারেশনে 5-15% ওভারহেড যোগ করে।
SQLite একটি এমবেডেড লাইব্রেরি যার সার্ভার প্রক্রিয়ার প্রয়োজন নেই। MySQL একটি ক্লায়েন্ট-সার্ভার DBMS যার আলাদা সার্ভার, ব্যবহারকারী, অ্যাক্সেস অধিকার এবং নেটওয়ার্ক প্রোটোকল রয়েছে। SQLite ডেটাবেস একটি ফাইলে সংরক্ষণ করে; MySQL এটি সার্ভার দ্বারা পরিচালিত একাধিক ফাইলে সংরক্ষণ করে। SQLite সহজ এবং হালকা; MySQL আরও শক্তিশালী এবং স্কেলেবল।
SQLite মাইগ্রেশন-এর জন্য, ALTER TABLE (কলাম যোগ করা) ব্যবহার করুন অথবা ডেটা স্থানান্তর এবং পুরানো টেবিল মুছে ফেলার সাথে নতুন টেবিল তৈরি করুন। Room Migration ক্লাসের মাধ্যমে এই প্রক্রিয়াটি স্বয়ংক্রিয় করে: startVersion, endVersion এবং স্কিমা পরিবর্তনের জন্য SQL কোয়েরি উল্লেখ করুন। GRDB এবং FMDB অনুরূপ DatabaseMigrator প্রদান করে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন