모바일 개발의 데이터 스토리지: 개념, 방법 및 작동 방식

저자: IT Sectr 게시일: 2026-03-08 읽는 시간: 9 분

데이터 스토리지는 모바일 애플리케이션의 핵심 작업 중 하나로, 성능, 보안 및 사용자 경험에 영향을 미칩니다. 이 글에서는 SQLite, Room, Core Data, Realm, Firebase Firestore, SharedPreferences, DataStore, Keystore, Keychain과 직렬화 형식(JSON, Protobuf) 및 라이브러리(Gson, Moshi, kotlinx.serialization)를 다룹니다. 이 가이드는 초보 개발자가 올바른 데이터 스토리지 솔루션을 선택하는 데 도움을 줍니다. 자세한 내용은 공식 Android 데이터 스토리지 가이드를 참조하세요.

주요 포인트

  • Room(Android)과 Core Data(iOS)는 각 플랫폼에서 관계형 데이터베이스를 다루는 공식 ORM입니다
  • SharedPreferences(Android)는 DataStore로 대체되고 있습니다 — 비동기 및 타입 안전 키-값 스토리지
  • 토큰의 안전한 저장을 위해 하드웨어 보호와 함께 Keystore(Android)와 Keychain(iOS)을 사용합니다
  • Firebase Firestore는 실시간 동기화 및 오프라인 모드를 갖춘 NoSQL 데이터베이스입니다
  • 직렬화 — Gson, Moshi, kotlinx.serialization을 통한 객체를 JSON/Protobuf로 변환

로컬 데이터베이스: SQLite, Room, Core Data, Realm

엔터티 간의 관계가 있는 구조화된 데이터를 저장하기 위해 관계형 데이터베이스가 사용됩니다.

SQLite

SQLite는 모든 모바일 플랫폼에서 작동하는 임베디드 관계형 데이터베이스입니다. 별도의 서버가 필요하지 않으며 데이터는 단일 파일에 저장됩니다. SQLite는 Room(Android)의 기반이며 선택적으로 Core Data(iOS)의 기반입니다. 라이브러리: android.database.sqlite(Android), FMDB/Core Data(iOS), sqflite(Flutter).

Room (Android)

Room은 SQLite를 다루기 위한 공식 Android Architecture Components 라이브러리입니다. ORM 계층을 제공합니다: Entity(테이블), DAO(쿼리), Database(진입점). Room은 컴파일 타임에 SQL 쿼리를 검사하고, 코루틴과 Flow를 지원하며, 스키마를 자동으로 마이그레이션합니다.

kotlin
@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 (iOS)

Core Data는 객체 그래프를 관리하는 Apple의 프레임워크입니다. 순수 데이터베이스가 아니라 SQLite, XML 또는 바이너리 스토리지 위의 지속성 계층입니다. Core Data는 객체(NSManagedObject), 관계, 스키마 버전 관리, 실행 취소/다시 실행 및 NSManagedObjectContext를 통한 멀티스레딩을 관리합니다.

Realm

Realm은 SQLite의 대안으로 설계된 고성능 모바일 데이터베이스입니다. Realm은 읽기 및 쓰기에서 SQLite보다 빠르며, 반응형 알림(Live Objects), 실시간 암호화 및 크로스 플랫폼(Android, iOS, Flutter, React Native)을 지원합니다. 단점: APK/IPA 크기 증가 및 더 많은 메모리 사용.

키-값 스토리지 및 설정

소량의 데이터(설정, 토큰, 캐시)를 저장하기 위해 간단한 키-값 저장소가 사용됩니다.

SharedPreferences (Android)

SharedPreferences는 Android의 레거시 키-값 저장소입니다. 단점: 동기 액세스(읽기 시 UI 차단), 타입 지정 부족, 대용량 파일 로드 시 ANR 위험. 새 프로젝트에는 권장되지 않습니다.

DataStore (Jetpack Android)

DataStore는 Google의 SharedPreferences를 대체하는 최신 도구입니다. Kotlin Coroutines와 Flow를 통해 비동기로 작동하며, Preferences DataStore(키-값) 및 Proto DataStore(Protobuf를 통한 타입 지정 데이터)를 지원합니다. DataStore는 UI 스레드에 안전하며 트랜잭션을 지원합니다.

NSUserDefaults (iOS)

UserDefaults는 iOS에서 작은 설정을 위한 표준 저장소입니다. 기본 타입, 문자열, 날짜, Data를 지원합니다. UserDefaults는 동기식이므로 대용량 데이터에는 적합하지 않습니다. register(defaults:)를 통한 값 등록으로 기본값을 설정합니다.

클라우드 데이터베이스: Firebase Firestore 및 Realtime DB

장치 간 동기화가 필요한 애플리케이션의 데이터 저장을 위해 Firebase 클라우드 데이터베이스가 사용됩니다.

Cloud Firestore

Firebase Firestore는 실시간 구독, 자동 확장, 강력한 쿼리 및 내장 오프라인 모드를 갖춘 NoSQL 문서 데이터베이스입니다. 데이터는 컬렉션과 문서(JSON 유사 구조)로 구성됩니다. Firestore는 트랜잭션 및 배치 작업을 지원합니다. 채팅, 피드 및 소셜 앱에 이상적입니다.

Firebase Realtime Database

Firebase Realtime Database는 데이터를 단일 JSON 트리로 저장하는 이전 Firebase NoSQL 데이터베이스입니다. Firestore보다 단순하지만 쿼리 및 확장에서 유연성이 떨어집니다. 간단한 실시간 애플리케이션(온라인 상태, 간단한 채팅)에 권장됩니다.

특징 Cloud Firestore Firebase Realtime DB
데이터 모델컬렉션 → 문서JSON 트리
쿼리복잡(필터링, 정렬, 제한)단순(키 기준)
확장자동수동 샤딩
오프라인 모드예(영구 캐시)
가격읽기/쓰기 작업당트래픽 + 스토리지당

보안 스토리지: Keystore, Keychain 및 EncryptedSharedPreferences

토큰, 비밀번호 및 암호화 키 저장을 위해서는 특별한 보호 저장소가 필요합니다.

Android Keystore

Android Keystore는 암호화 키를 위한 시스템 저장소입니다. 키는 하드웨어 환경(TEE — Trusted Execution Environment)에 저장되어 앱과 OS에서 접근할 수 없습니다. 키 생성, 암호화 및 서명을 지원합니다. Android 9+에는 StrongBox Keymaster(전용 칩)가 포함됩니다.

iOS Keychain

Keychain Services는 비밀번호, 키 및 인증서를 위한 안전한 iOS 저장소입니다. 데이터는 하드웨어 Secure Enclave를 사용하여 암호화됩니다. Keychain은 접근성 수준을 지원합니다: Always, WhenUnlocked, WhenUnlockedThisDeviceOnly, AfterFirstUnlock.

EncryptedSharedPreferences (Android)

EncryptedSharedPreferences는 AES256-GCM 및 HKDF를 통한 키-값 암호화가 포함된 SharedPreferences 래퍼입니다. AndroidX Security 라이브러리에 구현되어 있습니다. 토큰 및 민감한 설정 저장에 권장됩니다.

IT Sectr에서는 리프레시 토큰과 생체 인식 기반 키 저장을 위해 Android Keystore + EncryptedSharedPreferences를 사용합니다. iOS에서는 최대 보안을 위해 kSecAttrAccessibleWhenUnlockedThisDeviceOnly 수준의 Keychain을 사용합니다.

파일 스토리지: Internal, External, Cache Directory

파일 저장(이미지, 비디오, 문서)을 위해 모바일 플랫폼은 여러 유형의 스토리지를 제공합니다.

Android Storage

Android는 Internal Storage(/data/data/패키지/ — 비공개 저장소)와 External Storage(SD 카드 또는 에뮬레이션된 파티션)를 구분합니다. Cache Directory는 시스템이 지울 수 있는 임시 저장소입니다. Scoped Storage(Android 10+)는 External Storage에 대한 접근을 제한합니다 — 앱은 자신의 파일 또는 MediaStore/SAF를 통한 파일만 볼 수 있습니다.

iOS Storage

iOS는 Documents Directory(iCloud 백업, 영구 데이터), Library/Caches(임시 파일, 백업 안 됨) 및 Tmp Directory(임시, 지울 수 있음)를 제공합니다. 파일 시스템 작업에는 NSFileManager를 사용합니다. iOS 11+는 클라우드 파일을 위한 File Provider를 지원합니다.

데이터 직렬화: JSON, Protobuf 및 라이브러리

직렬화는 객체를 전송 또는 저장을 위한 형식으로 변환합니다. 역직렬화는 반대 과정입니다.

형식

JSON(JavaScript Object Notation)은 가장 인기 있는 형식입니다: 읽기 쉽고, 유연하며, 모든 플랫폼에서 지원됩니다. XML은 더 엄격하며 레거시 시스템에서 사용됩니다. Protobuf(Protocol Buffers)는 Google의 바이너리 형식입니다: JSON보다 3-10배 더 작고, 구문 분석이 빠르며, 엄격한 스키마가 있습니다. 고부하 시스템 및 마이크로서비스에 사용됩니다.

Android 라이브러리

  • Gson(Google) — 간단하고 유연하지만 느림. Java/Kotlin 객체와 자동으로 작동
  • Moshi(Square) — Gson보다 빠르며 Kotlin 지원 우수(널이 아닌 속성, 기본값, sealed 클래스)
  • kotlinx.serialization — JetBrains의 네이티브 Kotlin 직렬화, 컴파일 타임에 작동, JSON, Protobuf, CBOR 지원

iOS 라이브러리

JSONSerialization은 JSON 작업을 위한 내장 API입니다. Codable(Encodable/Decodable)은 JSON, Property List 및 기타 형식으로 자동 직렬화를 위한 현대적인 Swift 프로토콜입니다.

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

크로스 플랫폼 솔루션: Hive, ObjectBox, Drift

Flutter 및 React Native에는 자체 효율적인 스토리지 라이브러리가 있습니다.

Hive (Flutter)

Hive는 Flutter용 경량 고속 키-값 저장소입니다. 네이티브 코드가 필요 없으며(순수 Dart), TypeAdapter를 통한 타입 지정을 지원하고, 격리 상태에서 작동합니다. 캐시, 설정 및 소량의 데이터에 이상적입니다.

ObjectBox

ObjectBox는 Flutter, Android 및 iOS용 고성능 임베디드 데이터베이스입니다. SQLite보다 10배 이상 빠르며, 최소 오버헤드를 위해 플랫 파일 구조를 사용합니다. 관계, 쿼리 및 반응형 구독(ObjectBox Dart)을 지원합니다.

Drift (이전 Moor)

Drift는 Flutter 및 Dart용 반응형 SQLite 라이브러리입니다. 타입 안전 쿼리, 마이그레이션, DAO 함수 및 Stream 지원(반응형 업데이트)을 제공합니다. Drift는 SQLite가 필요한 Flutter 프로젝트의 주요 선택입니다.

자주 묻는 질문

로컬 데이터 저장에 Room과 Core Data 중 무엇이 더 좋나요?

플랫폼에 따라 다릅니다: Room(Android)은 컴파일 타임 쿼리 검사가 있는 SQLite 기반 공식 라이브러리입니다. Core Data(iOS)는 객체 그래프가 있는 Apple의 프레임워크입니다. 크로스 플랫폼 프로젝트에는 Realm 또는 ORM을 통한 SQLite가 적합합니다.

SharedPreferences와 DataStore의 차이점은 무엇인가요?

SharedPreferences는 동기 액세스 및 ANR 위험이 있는 오래된 구현입니다. DataStore(Jetpack)는 Kotlin Coroutines 및 Flow 기반의 현대적인 대체품으로, 비동기, 타입 지정 및 오류 보호를 지원합니다.

모바일 앱에서 토큰과 비밀번호를 안전하게 저장하는 방법은?

Android: EncryptedSharedPreferences 또는 Android Keystore. iOS: WhenUnlockedThisDeviceOnly 접근성의 Keychain Services. 중요 데이터의 경우 생체 인증과 함께 Secure Enclave(iOS) 및 하드웨어 Keystore(Android)를 사용하세요.

Firebase Firestore란 무엇이며 언제 사용해야 하나요?

Cloud Firestore는 실시간 동기화, 오프라인 모드 및 자동 확장을 갖춘 Firebase의 NoSQL 데이터베이스입니다. 채팅, 뉴스 피드 및 장치 간 동기화가 필요한 프로젝트에 적합합니다.

Flutter 및 React Native용 ORM에는 무엇이 있나요?

Flutter: Hive(빠른 키-값), Floor(SQLite ORM), Drift(Moor, 반응형 SQLite), ObjectBox(고성능 임베디드 DB). React Native: Realm, WatermelonDB(지연 로딩) 및 AsyncStorage(SharedPreferences 유사).

요약

  • Room(Android)과 Core Data(iOS)는 각 플랫폼의 관계형 데이터베이스를 위한 공식 솔루션
  • DataStore는 비동기 설정 저장을 위해 SharedPreferences를 대체
  • Keystore / Keychain은 토큰 및 키의 안전한 저장에 필수
  • Firebase Firestore는 장치 간 실시간 동기화에 가장 적합한 선택
  • Kotlinx.serialization(Android)과 Codable(iOS)은 현대적인 직렬화 방식
  • Flutter: Drift(SQLite), Hive(키-값), ObjectBox(고성능)
  • Realm은 반응형 알림이 있는 SQLite의 크로스 플랫폼 대안

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의