การจัดเก็บข้อมูลเป็นหนึ่งในงานหลักของแอปพลิเคชันมือถือ ซึ่งส่งผลต่อประสิทธิภาพ ความปลอดภัย และประสบการณ์ผู้ใช้ ในบทความนี้เราจะกล่าวถึง SQLite, Room, Core Data, Realm, Firebase Firestore, SharedPreferences, DataStore, Keystore และ Keychain รวมถึงรูปแบบการซีเรียลไลซ์ (JSON, Protobuf) และไลบรารี (Gson, Moshi, kotlinx.serialization) คู่มือนี้จะช่วยให้นักพัฒนามือใหม่เลือกโซลูชันการจัดเก็บข้อมูลที่เหมาะสม ดูรายละเอียดเพิ่มเติมได้ที่ คู่มืออย่างเป็นทางการของ Android เกี่ยวกับการจัดเก็บข้อมูล
ประเด็นสำคัญ
สำหรับการจัดเก็บข้อมูลที่มีโครงสร้างพร้อมความสัมพันธ์ระหว่างเอนทิตี จะใช้ฐานข้อมูลเชิงสัมพันธ์
SQLite เป็นฐานข้อมูลเชิงสัมพันธ์แบบฝังที่ทำงานบนแพลตฟอร์มมือถือใดก็ได้ ไม่ต้องใช้เซิร์ฟเวอร์แยกต่างหาก ข้อมูลถูกเก็บในไฟล์เดียว SQLite เป็นพื้นฐานสำหรับ Room (Android) และเลือกใช้สำหรับ Core Data (iOS) ไลบรารี: android.database.sqlite (Android), FMDB/Core Data (iOS), sqflite (Flutter)
Room เป็นไลบรารี Android Architecture Components อย่างเป็นทางการสำหรับทำงานกับ SQLite มีเลเยอร์ ORM: Entity (ตาราง), DAO (คิวรี), Database (จุดเริ่มต้น) Room ตรวจสอบคิวรี SQL ในเวลาคอมไพล์ รองรับ coroutines และ Flow และโยกย้ายสคีมาโดยอัตโนมัติ
@Entity data class User( @PrimaryKey val id: Int, val name: String, val email: String ) @Dao interface UserDao { @Query("SELECT * FROM user WHERE id = :id") suspend fun getUser(id: Int): User? }
Core Data เป็นเฟรมเวิร์กของ Apple สำหรับจัดการกราฟออบเจกต์ ไม่ใช่ฐานข้อมูลบริสุทธิ์ — เป็นเลเยอร์ความคงทนเหนือ SQLite, XML หรือพื้นที่จัดเก็บไบนารี Core Data จัดการออบเจกต์ (NSManagedObject), ความสัมพันธ์, การกำหนดเวอร์ชันสคีมา, เลิกทำ/ทำซ้ำ และการทำงานหลายเธรดผ่าน NSManagedObjectContext
Realm เป็นทางเลือกของ SQLite ออกแบบมาเป็นฐานข้อมูลมือถือประสิทธิภาพสูง Realm เร็วกว่า SQLite ในการอ่านและเขียน รองรับการแจ้งเตือนแบบรีแอกทีฟ (Live Objects), การเข้ารหัสทันที และข้ามแพลตฟอร์ม (Android, iOS, Flutter, React Native) ข้อเสีย: ขนาด APK/IPA เพิ่มขึ้นและการใช้หน่วยความจำมากขึ้น
สำหรับการจัดเก็บข้อมูลปริมาณน้อย (การตั้งค่า, โทเค็น, แคช) จะใช้พื้นที่จัดเก็บคู่คีย์-ค่าแบบง่าย
SharedPreferences เป็นพื้นที่จัดเก็บคู่คีย์-ค่าแบบเดิมใน Android ข้อเสีย: การเข้าถึงแบบซิงโครนัส (บล็อก UI ขณะอ่าน), ขาดการกำหนดชนิด, ความเสี่ยง ANR เมื่อโหลดไฟล์ขนาดใหญ่ ไม่แนะนำสำหรับโปรเจกต์ใหม่
DataStore เป็นสิ่งทดแทน SharedPreferences สมัยใหม่จาก Google ทำงานแบบอะซิงโครนัสผ่าน Kotlin Coroutines และ Flow รองรับ Preferences DataStore (คีย์-ค่า) และ Proto DataStore (ข้อมูลชนิดที่กำหนดผ่าน Protobuf) DataStore ปลอดภัยสำหรับเธรด UI และรองรับธุรกรรม
UserDefaults เป็นพื้นที่จัดเก็บมาตรฐานสำหรับการตั้งค่าเล็กน้อยใน iOS รองรับชนิดพื้นฐาน, สตริง, วันที่, Data UserDefaults เป็นแบบซิงโครนัส จึงไม่เหมาะสำหรับข้อมูลปริมาณมาก การลงทะเบียนค่าผ่าน register(defaults:) กำหนดค่าเริ่มต้น
สำหรับการจัดเก็บข้อมูลในแอปพลิเคชันที่ต้องการการซิงค์ระหว่างอุปกรณ์ จะใช้ฐานข้อมูลคลาวด์ Firebase
Firebase Firestore เป็นฐานข้อมูลเอกสาร NoSQL ที่มีการสมัครสมาชิกแบบเรียลไทม์, การปรับขนาดอัตโนมัติ, คิวรีทรงพลัง และโหมดออฟไลน์ในตัว ข้อมูลถูกจัดเป็นคอลเล็กชันและเอกสาร (โครงสร้างคล้าย JSON) Firestore รองรับธุรกรรมและการดำเนินการแบบแบตช์ เหมาะสำหรับแชท, ฟีด และแอปโซเชียล
Firebase Realtime Database เป็นฐานข้อมูล NoSQL รุ่นเก่าของ Firebase ที่เก็บข้อมูลเป็นต้นไม้ JSON เดียว ง่ายกว่า Firestore แต่ยืดหยุ่นน้อยกว่าในการคิวรีและการปรับขนาด แนะนำสำหรับแอปพลิเคชันเรียลไทม์แบบง่าย (สถานะออนไลน์, แชทง่าย)
| คุณลักษณะ | Cloud Firestore | Firebase Realtime DB |
|---|---|---|
| โมเดลข้อมูล | คอลเล็กชัน → เอกสาร | ต้นไม้ JSON |
| คิวรี | ซับซ้อน (การกรอง, การเรียง, ข้อจำกัด) | ง่าย (ตามคีย์) |
| การปรับขนาด | อัตโนมัติ | การแบ่งส่วนด้วยตนเอง |
| โหมดออฟไลน์ | ใช่ (แคชถาวร) | ใช่ |
| ราคา | ต่อการดำเนินการอ่าน/เขียน | ต่อปริมาณการใช้งาน + พื้นที่จัดเก็บ |
การจัดเก็บโทเค็น, รหัสผ่าน และคีย์เข้ารหัสต้องใช้พื้นที่จัดเก็บที่ป้องกันเป็นพิเศษ
Android Keystore เป็นพื้นที่จัดเก็บระบบสำหรับคีย์เข้ารหัส คีย์ถูกเก็บในสภาพแวดล้อมฮาร์ดแวร์ (TEE — Trusted Execution Environment) ที่แอปและระบบปฏิบัติการไม่สามารถเข้าถึงได้ รองรับการสร้างคีย์, การเข้ารหัส และการลงนาม Android 9+ มี StrongBox Keymaster (ชิปเฉพาะ)
Keychain Services เป็นพื้นที่จัดเก็บที่ปลอดภัยของ iOS สำหรับรหัสผ่าน, คีย์ และใบรับรอง ข้อมูลถูกเข้ารหัสโดยใช้ Secure Enclave ของฮาร์ดแวร์ Keychain รองรับระดับการเข้าถึง: Always, WhenUnlocked, WhenUnlockedThisDeviceOnly, AfterFirstUnlock
EncryptedSharedPreferences เป็นตัวหุ้มรอบ SharedPreferences พร้อมการเข้ารหัสคีย์และค่าผ่าน AES256-GCM และ HKDF ใช้งานในไลบรารี AndroidX Security แนะนำสำหรับจัดเก็บโทเค็นและการตั้งค่าที่ละเอียดอ่อน
ที่ IT Sectr เราใช้ Android Keystore + EncryptedSharedPreferences สำหรับจัดเก็บรีเฟรชโทเค็นและคีย์ไบโอเมตริกซ์ บน iOS เราใช้ Keychain ด้วยระดับ kSecAttrAccessibleWhenUnlockedThisDeviceOnly เพื่อความปลอดภัยสูงสุด
สำหรับการจัดเก็บไฟล์ (รูปภาพ, วิดีโอ, เอกสาร) แพลตฟอร์มมือถือมีพื้นที่จัดเก็บหลายประเภท
Android แยกความแตกต่างระหว่าง Internal Storage (/data/data/แพ็กเกจ/ — พื้นที่จัดเก็บส่วนตัว) และ External Storage (การ์ด SD หรือพาร์ติชันจำลอง) Cache Directory เป็นพื้นที่จัดเก็บชั่วคราวที่ระบบสามารถล้างได้ Scoped Storage (Android 10+) จำกัดการเข้าถึง External Storage — แอปเห็นเฉพาะไฟล์ของตัวเองหรือไฟล์ผ่าน MediaStore/SAF
iOS มี Documents Directory (สำรอง iCloud, ข้อมูลถาวร), Library/Caches (ไฟล์ชั่วคราว, ไม่สำรอง) และ Tmp Directory (ชั่วคราว, สามารถล้างได้) ใช้ NSFileManager สำหรับทำงานกับระบบไฟล์ iOS 11+ รองรับ File Provider สำหรับไฟล์คลาวด์
การซีเรียลไลซ์แปลงออบเจกต์เป็นรูปแบบสำหรับการส่งหรือจัดเก็บ การดีซีเรียลไลซ์เป็นกระบวนการย้อนกลับ
JSON (JavaScript Object Notation) เป็นรูปแบบที่นิยมที่สุด: อ่านได้, ยืดหยุ่น, รองรับโดยทุกแพลตฟอร์ม XML เข้มงวดกว่า ใช้ในระบบเดิม Protobuf (Protocol Buffers) เป็นรูปแบบไบนารีจาก Google: กะทัดรัดกว่า JSON 3-10 เท่า, แยกวิเคราะห์เร็วกว่า, มีสคีมาเข้มงวด ใช้สำหรับระบบโหลดสูงและไมโครเซอร์วิส
JSONSerialization เป็น API ในตัวสำหรับทำงานกับ JSON Codable (Encodable/Decodable) เป็นโปรโตคอล Swift สมัยใหม่สำหรับการซีเรียลไลซ์อัตโนมัติเป็น JSON, Property List และรูปแบบอื่นๆ
struct User: Codable { let id: Int let name: String let email: String } let user = User(id: 1, name: "Alice", email: "alice@example.com") let encoder = JSONEncoder() let jsonData = try encoder.encode(user)
สำหรับ Flutter และ React Native มีไลบรารีจัดเก็บข้อมูลที่มีประสิทธิภาพเฉพาะ
Hive เป็นพื้นที่จัดเก็บคู่คีย์-ค่าแบบเบาและเร็วสำหรับ Flutter ไม่ต้องใช้โค้ดดั้งเดิม (Dart บริสุทธิ์), รองรับการกำหนดชนิดผ่าน TypeAdapter, ทำงานใน isolates เหมาะสำหรับแคช, การตั้งค่า และข้อมูลปริมาณน้อย
ObjectBox เป็นฐานข้อมูลฝังประสิทธิภาพสูงสำหรับ Flutter, Android และ iOS เร็วกว่า SQLite 10+ เท่า, ใช้โครงสร้างไฟล์แบบแบนเพื่อโอเวอร์เฮดน้อยที่สุด รองรับความสัมพันธ์, คิวรี และการสมัครสมาชิกแบบรีแอกทีฟ (ObjectBox Dart)
Drift เป็นไลบรารี SQLite แบบรีแอกทีฟสำหรับ Flutter และ Dart มีคิวรีที่ปลอดภัยชนิด, การโยกย้าย, ฟังก์ชัน DAO และการสนับสนุน Stream (อัปเดตแบบรีแอกทีฟ) Drift เป็นตัวเลือกหลักสำหรับโปรเจกต์ Flutter ที่ต้องการ SQLite
คำถามที่พบบ่อย
การเลือกขึ้นอยู่กับแพลตฟอร์ม: Room (Android) เป็นไลบรารีอย่างเป็นทางการบน SQLite พร้อมการตรวจสอบคิวรีในเวลาคอมไพล์ Core Data (iOS) เป็นเฟรมเวิร์กของ Apple พร้อมกราฟออบเจกต์ สำหรับโปรเจกต์ข้ามแพลตฟอร์ม Realm หรือ SQLite ผ่าน ORM เหมาะสม
SharedPreferences เป็นการใช้งานเก่าที่มีการเข้าถึงแบบซิงโครนัสและความเสี่ยง ANR DataStore (Jetpack) เป็นสิ่งทดแทนสมัยใหม่บน Kotlin Coroutines และ Flow รองรับอะซิงโครนัส, การกำหนดชนิด และการป้องกันข้อผิดพลาด
Android: EncryptedSharedPreferences หรือ Android Keystore iOS: Keychain Services ด้วยระดับการเข้าถึง WhenUnlockedThisDeviceOnly สำหรับข้อมูลสำคัญ ใช้ Secure Enclave (iOS) และ Keystore ฮาร์ดแวร์ (Android) พร้อมไบโอเมตริกซ์
Cloud Firestore เป็นฐานข้อมูล NoSQL จาก Firebase ที่มีการซิงค์แบบเรียลไทม์, โหมดออฟไลน์ และการปรับขนาดอัตโนมัติ เหมาะสำหรับแชท, ฟีดข่าว และโปรเจกต์ที่ต้องการการซิงค์ระหว่างอุปกรณ์
Flutter: Hive (คีย์-ค่าเร็ว), Floor (ORM SQLite), Drift (Moor, SQLite แบบรีแอกทีฟ), ObjectBox (ฐานข้อมูลฝังประสิทธิภาพสูง) React Native: Realm, WatermelonDB (โหลดขี้เกียจ) และ AsyncStorage (คล้าย SharedPreferences)
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ