본문 바로가기

기타

[SQLite] SQLite 설명 및 예제

반응형

프로젝트를 진행하면서 DB 를 사용해야 하는 상황이 발생했다. 프로젝트의 프로토타이핑 과정이었기 때문에 다양한 기능과 성능보다는 간단한 설정과 빠르게 적용할 수 있는 DB 가 필요했고 SQLite 를 사용하기로 했다. SQLite 는 File DB 로 가볍고 따로 DB 서버를 설정할 필요가 없고 간편하게 사용할 수 있다. 이 글에서는 SQLite 에 대한 소개와 간단한 사용 방법을 정리하려고 한다.

 

1. SQLite 란?

 

SQLite 는 가볍고, 빠르며, 독립적인 SQL Database 엔진을 구현하는 C 언어 라이브러리이다.

SQLite 는 내장형 SQL DB 엔진으로 MySQL 이나 PostgreSQL 과 같은 기존의 RDBMS 와 달리 서버리스이며 실행을 위해 별도의 설치나 설정이 필요하지 않다. 대신 SQLite 를 사용하는 애플리케이션의 내부에 일반 디스크 파일로 저장되어 직접 읽고 쓰여진다. SQLite DB 는 하나의 파일에 multi table, index, trigger, view 등의 기능이 포함된다.

SQLite 의 DB 파일은 크로스 플랫폼을 지원한다. 32bit, 64bit 또는 big-endian, little-endian architecture 등에서 모두 호환되어서 사용할 수 있다.

이외에도 매우 작은 메모리 환경에서도 잘 동작하기 때문에 많은 애플리케이션 파일 형식으로 사용된다.

 

2. SQLite 특징

 

SQLite 는 앞서 설명한 것과 같이 가볍고, 사용에 편리한 RDBMS 이다. 또한 DB 가 파일로 저장되기 때문에 임베디드 애플리케이션과 같이 가볍고 내장된 DB 가 필요한 경우에 사용하기 좋다. 또한 로컬 DB 가 필요하거나 데이터 저장이 필요하지만 본격적인 DBMS 가 필요하지 않은 경우에 SQLite 를 많이 사용한다.

아래에서는 SQLite 공식문서에서 다른 SQL Database 들과 구분되는 특징들을 정리한 내용이다.

 

- Zero-Configuration

 

SQLite 를 사용하기 위해서 SQLite 라이브러리 외에 따로 설치하거나 환경설정을 해주지 않아도 된다. 따로 서버로 동작하지 않기 때문에 SQLite 를 시작, 중단, 설정하는 등의 과정을 거치지 않아도 된다. 다른 DBMS 처럼 Admin 계정으로 DB 객체를 생성하고 이에 대한 권한을 사용자에게 할당하여 사용하도록 할 필요도 없다. 그 외에도 별도의 설정 파일이나, DB 동작 확인, 시스템 충돌시의 복구 프로세스등도 필요하지 않다.

다른 여러 DB 엔진들은 초기 설치와 설정 등이 필요하지만 SQLite 는 이러한 복잡한 과정을 거치지 않고도 사용할 수 있다.

 

- Serverless

 

대부분의 SQL DB 엔진들은 분리된 서버 프로세스로 구현되어있다. 이때문에 프로그램에서 DB 를 사용하기 위해서는 TCP 통신 등을 통해 DB 서버와 request 를 전송하고 이에 대한 결과를 response 로 받는 방식으로 동작한다.

SQLite 는 서버 프로세스로 동작하지 않는다. DB 에 접근하고 싶은 프로세스가 직접 파일 디스크의 파일에 접근하여 읽고 쓰는 방식으로 동작한다.

물론 서버리스 방식에는 장단점이 있다. 가장 큰 장점은 Zero-Configuration 에서 설명한 것처럼 DB 를 사용하기 위해 따로 서버를 실행하거나 DB 서버의 초기화, 설정, 관리 운영 등을 별도로 할 필요가 없다는 것이다. DB 에 접근하려는 프로그램은 특별한 설정없이 파일 디스크에 있는 SQLite DB 파일에 접근하면 된다.

반면에 Database 의 보안, 데이터 보호 등에서는 서버 방식이 더 유리하다. 클라이언트와 분리되어 있기 때문에 클라이언트 애플리케이션의 버그로부터 데이터를 보호할 수 있고, 애플리케이션이 직접 DB 에 접근하여 메모리를 손상시키는 것을 방지할 수 있다.

 

- Single Database File

 

SQLite database 는 한개의 평범한 디스크 파일이다. 해당 파일에 대한 읽기, 쓰기권한만 있다면 얼마든지 database 의 데이터들을 읽고 쓸 수 있다. 또한 파일을 전달하여 간편하게 database 를 공유할 수 있다.

대부분의 SQL database 엔진들은 여러개의 많은 파일 컬렉션으로 데이터를 저장한다. 일반적으로 해당 파일들은 특정 위치에 저장되어 DB 엔진만 접근할 수 있도록 되어있다. 이러한 방식이 보안적으로는 유리하지만 데이터에 접근하는 것은 어렵게 한다.

 

- Stable Cross-Platform Database File

 

SQLite 의 파일 형식은 Cross-Platform 이다. 한 시스템에서 작성된 DB 파일을 다른 아키텍쳐를 가진 시스템으로 옮겨도 문제없이 사용할 수 있다. Big-endian, Little-endian 또는 32bit, 64bit 에 관계없이 모든 장치에서 동일한 파일 형식을 사용한다.

 

- Compact

 

SQLite 의 DB 파일은 크기가 굉장히 작다. 최적화된 경우 모든 기능이 활성화된 SQLite 의 크기가 500KiB 미만이다. 모든 기능을 사용하지 않는 경우에는 컴파일 시에 불필요한 기능을 비활성화하여 300KiB 미만으로 더 줄일 수 있다.

 

- Manifest typing

 

대부분의 SQL DB 엔진들은 정적 타이핑을 사용한다. 데이터 타입은 테이블의 각 열과 연결되어서 해당 열에는 특정한 데이터 타입만 저장될 수 있다. SQLite 는 manifest typing 을 사용하여 이러한 제한을 완화하였다. Manifest typing 에서 데이터 타입은 값이 저장되는 열이 아니라 데이터 값 자체가 가지고 있다. 이를 사용해서 사용자는 해당 열에 선언된 데이터 타입과 관계없이 다양한 데이터 타입의 값을 저장할 수 있도록 한다.

이렇게 동적으로 타입을 정할 수 있도록 하는 Manifest typing 특성으로 SQLite 는 Tcl 이나 파이썬과 같은 동적 타이핑 언어와 함께 사용할때 조합이 좋다.

 

- Variable-length records

 

대부분의 SQL DB 엔진들은 테이블의 각 행에 고정된 디스크 공간을 할당한다. 실제 저장되는 데이터의 값이 할당된 값보다 작은 경우에도 똑같이 고정된 디스크 공간을 할당한다.

반면 SQLite 는 저장하는 데이터의 실제 크기만큼의 디스크 공간만 사용한다. 이러한 특징때문에 데이터베이스 파일을 더 작게 유지할 수 있다.

이외에도 SQLite 는 다양한 특징들을 가지고 있는데 자세한 내용은 아래의 링크에서 확인할 수 있다.

https://www.sqlite.org/different.html

 

3. SQLite 사용 예제

 

python 에서는 sqlite3 모듈을 사용하여 SQLite database 를 사용할 수 있다.
아래는 python 을 이용한 SQLite사용 예제이다.

 

import sqlite3

# Connect to the database (or create it if it doesn't exist)
conn = sqlite3.connect('mydatabase.db')

# Connect to in-memory database
# conn = sqlite3.connect(':memory:')

# Create a cursor object to execute SQL commands
cursor = conn.cursor()

# Create a table
cursor.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)")

# Insert data into the table
cursor.execute("INSERT INTO users (name, email) VALUES (?, ?)", ('John Doe', 'john@example.com'))

# Commit the changes
conn.commit()

# Query the database
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())

# Close the cursor and connection
cursor.close()
conn.close()

 

sqlite3.connect(...) 함수를 통해서 SQLite databbase 에 연결한다. 이때 connect 함수의 인자로 database 파일의 경로를 입력한다. 이 코드에서는 "mydatabase.db" 라는 db 파일에 접근하는데, 해당 파일이 없는 경우 자동으로 생성된다. 만약 in-memory database 를 사용하고 싶으면 db 파일의 경로 대신에 ":memory:" 를 입력하여 실제 db 파일이 아닌 메모리 db 에 연결된다.

conn.curosr(...) 함수로 database connection 에서 cursor 를 생성하여 쿼리들을 실행시킨다. cursor 의 execute(...) 함수로 쿼리를 실행하는데, SQL 명령어들을 string 타입의 인자로 입력한다. 이 예제에서는 users 라는 이름의 테이블을 생성하는 SQL 문을 실행한다.

execute(...) 함수는 SQL 문과 명령어에 입력되는 parameter 들을 입력할 수 있는데, INSERT 문을 실행하는 execute(...) 식을 보면 INSERT 문 쿼리문 다음에 ('John Doe', 'johm@example.com') 을 입력한다. 이들은 각각 "?" 기호로 입력된 곳에 대입되어서 쿼리를 완성하게 된다.

conn.commit() 함수를 통해서 변경사항을 저장하고 SELECT 문을 실행하여 users 테이블에 저장된 데이터를 가져온다. 이 데이터들은 cursor 에 저장되었다가 cursor.fetchall() 함수를 통해서 list 로 반환된다.

작업이 끝난 후에는 cursor.close() 와 conn.close() 를 호출하여 데이터베이스 연결 등을 해제한다.

 

[Reference]

https://www.sqlite.org/docs.html

 

SQLite Documentation

 

www.sqlite.org

https://runebook.dev/ko/docs/sqlite/different

 

SQLite - SQLite의 특징

Documentation Contributors GitHub

runebook.dev

 

반응형

'기타' 카테고리의 다른 글

[gRPC] Proto file 문법 (Message type, Service type)  (0) 2024.05.13
[gRPC] gRPC 와 Protocol Buffer  (0) 2024.05.09
[Celery] Celery 란?  (0) 2023.06.01
[FastAPI] BackgroundTasks  (0) 2023.05.26
[NGINX] NGINX 란?  (1) 2023.05.11