[플러터]SharedPreferences, 내부 저장소, SQLite의 차이점

임효진·2024년 1월 9일
0

Flutter

목록 보기
2/20

Flutter 앱 개발시 데이터 저장은 필수적인 부분이다.
사용자의 설정, 앱의 상태, 또는 사용자 데이터 등을 저장하기 위해 여러 옵션이 있다. 이 글에서는 Flutter에서 사용할 수 있는 세 가지 주요 데이터 저장 방법인 SharedPreferences, 내부 저장소, SQLite의 차이점과 사용 사례를 간략하게 살펴보겠다.

SharedPreferences

SharedPreferences는 키-값 쌍으로 데이터를 저장하는 방법으로, 간단한 데이터를 지속적으로 저장할 때 주로 사용된다.

특징

경량 데이터 저장: 사용자의 선호도나 설정 등 작은 데이터 세트를 저장하는 데 이상적이다.
간편성: 구현이 간단하고 사용하기 쉽다.
동기화: 데이터는 앱이 종료되거나 장치가 재부팅되더라도 유지된다.

사용 사례

  • 사용자의 테마 설정 (어두운 모드/밝은 모드)
  • 간단한 사용자 선호도 (예: 알림 설정)
  • 앱의 마지막 상태 저장

내부 저장소

Flutter에서 내부 저장소는 일반적으로 파일 시스템을 통해 데이터를 저장하는 방법을 말한다. 이는 주로 문자열, 이미지, 오디오 파일 등의 데이터를 저장하는 데 사용된다.

특징

유연성: 다양한 형태의 데이터(텍스트, 이미지, 오디오 파일 등)를 저장할 수 있다.
대용량 데이터 저장: 큰 파일이나 복잡한 데이터 구조를 저장할 수 있다.
개인 정보 보호: 저장된 데이터는 앱 전용이므로 다른 앱에서 접근할 수 없다.

사용 사례

  • 사용자가 생성한 파일 (예: 사진, 문서)
  • 앱이 다운로드한 콘텐츠
  • 로그 파일

SQLite

SQLite는 관계형 데이터베이스 관리 시스템으로, 복잡한 데이터 구조나 대용량 데이터를 효율적으로 관리할 수 있다.

특징
강력한 데이터 관리: 관계형 데이터베이스를 통해 복잡한 데이터 관리 및 쿼리가 가능하다.
트랜잭션 지원: 데이터 무결성을 보장한다.
대규모 데이터 처리: 대용량 데이터를 효율적으로 처리할 수 있다.
사용 사례

  • 사용자 프로필, 게시물, 댓글 등의 사용자 생성 콘텐츠 관리
  • 복잡한 데이터 구조가 필요한 앱 (예: 재무 관리, 쇼핑 목록)
  • 동기화가 필요한 앱 데이터

결론

Flutter에서 데이터를 저장하는 방법을 선택할 때는 데이터의 종류, 크기, 복잡성 및 앱의 요구 사항을 고려해야 한다. SharedPreferences는 간단한 설정이나 경량 데이터를 저장하는 데 적합하고, 내부 저장소는 대용량 또는 복잡한 파일을 저장하는 데 사용된다. 반면, SQLite는 복잡한 데이터 구조와 대용량 데이터를 효율적으로 관리하고자 할 때 최적의 선택이다. 각각의 방법은 독특한 장단점을 가지며, 앱의 특성에 맞게 적절히 선택하는 것이 중요하다.


활용사례

본인의 경우, 이미지와 여러 텍스트를 처리를 백엔드로 전송하기 전에 임시저장 기능을 구현하기 위해 데이터 종류를 고려하여 SQLite 데이터베이스를 구축했다.
구현 방법은 아래와 같이 설계했다.

데이터베이스 스키마 설계:

  • 단어, 예문, 품사, 동의어, 반의어, 이미지 등을 저장할 수 있는 테이블을 생성.
  • 예를 들어, Words 테이블에는 id, english_word, english_example, korean_word, part_of_speech, synonyms, antonyms, image_path 등의 컬럼이 있을 수 있었다.
  • image_path 컬럼은 이미지 파일의 경로를 저장할 수 있다. 실제 이미지 데이터는 파일 시스템에 저장하고, 그 경로만 데이터베이스에 저장하는 방식을 사용했다.

데이터 저장 및 로드 로직 구현:

  • 사용자가 데이터를 입력하면, 이를 SQLite 데이터베이스에 저장.
  • 앱이 시작될 때, 데이터베이스에서 데이터를 로드하여 사용자에게 보여줬다.
  • 이미지는 파일 시스템에 저장하고, 해당 경로를 데이터베이스에 저장한다.

데이터 전송 및 삭제 로직 구현:

  • 사용자가 "전송" 버튼을 누르면, 데이터를 백엔드로 전송한다.
  • 전송이 성공하면, 해당 데이터를 데이터베이스에서 삭제한다.
  • 이미지 파일도 파일 시스템에서 삭제한다.

  1. 먼저, pubspec.yaml 파일에 sqflitepath 패키지를 추가한다:
dependencies:
  flutter:
    sdk: flutter
  sqflite: ^2.0.0+4
  path: ^1.8.0
  1. 이제 기본적인 데이터베이스 헬퍼 클래스를 생성한다. 이 클래스는 데이터베이스를 초기화하고, 데이터를 추가, 검색, 삭제하는 기능을 포함한다:
import 'dart:io';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

class DatabaseHelper {
  static final _databaseName = "MyDatabase.db";
  static final _databaseVersion = 1;

  static final table = 'words_table';

  static final columnId = 'id';
  static final columnEnglishWord = 'english_word';
  static final columnEnglishExample = 'english_example';
  static final columnKoreanWord = 'korean_word';
  static final columnPartOfSpeech = 'part_of_speech';
  static final columnSynonyms = 'synonyms';
  static final columnAntonyms = 'antonyms';
  static final columnImagePath = 'image_path';

  // 싱글톤 클래스
  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  static Database _database;
  Future<Database> get database async {
    if (_database != null) return _database;
    _database = await _initDatabase();
    return _database;
  }

  _initDatabase() async {
    String path = join(await getDatabasesPath(), _databaseName);
    return await openDatabase(path,
        version: _databaseVersion,
        onCreate: _onCreate);
  }

  Future _onCreate(Database db, int version) async {
    await db.execute('''
          CREATE TABLE $table (
            $columnId INTEGER PRIMARY KEY,
            $columnEnglishWord TEXT NOT NULL,
            $columnEnglishExample TEXT,
            $columnKoreanWord TEXT,
            $columnPartOfSpeech TEXT,
            $columnSynonyms TEXT,
            $columnAntonyms TEXT,
            $columnImagePath TEXT
          )
          ''');
  }

  // Helper 메서드

  // DB에 row 삽입
  Future<int> insert(Map<String, dynamic> row) async {
    Database db = await instance.database;
    return await db.insert(table, row);
  }


  Future<List<Map<String, dynamic>>> queryAllRows() async {
    Database db = await instance.database;
    return await db.query(table);
  }

  Future<int> deleteAll() async {
    Database db = await instance.database;
    return await db.delete(table);
  }
}
  1. 이제 이 클래스를 사용하여 데이터를 삽입하고, 검색하고, 삭제하는 기본적인 작업을 수행할 수 있다. 예를 들어, 새로운 단어를 데이터베이스에 추가하는 방법은 다음과 같다:
void _addWord() async {
  Map<String, dynamic> row = {
    DatabaseHelper.columnEnglishWord: 'example',
    DatabaseHelper.columnEnglishExample: 'This is an example.',
    DatabaseHelper.columnKoreanWord: '예시',
    DatabaseHelper.columnPartOfSpeech: 'noun',
    DatabaseHelper.columnSynonyms: 'sample',
    DatabaseHelper.columnAntonyms: 'antonym',
    DatabaseHelper.columnImagePath: '/path/to/image.jpg'
  };
  final id = await DatabaseHelper.instance.insert(row);
  print('inserted row id: $id');
}
  1. 데이터베이스에서 모든 단어를 검색하려면 다음과 같이 할 수 있다:

void _queryAllWords() async {
  final allRows = await DatabaseHelper.instance.queryAllRows();
  allRows.forEach((row) => print(row));
}
  1. 데이터베이스에서 모든 데이터를 삭제하려면 다음과 같이 할 수 있다:
void _deleteAllWords()
profile
네트워크 엔지니어에서 풀스택 개발자로

0개의 댓글