SQLite 사용하기
안드로이드의 Data storage option
안드로이드 내 저장소를 이용하기 위한 방법에는 세 가지가 있다.
-
Files 사진 파일이나 음악 파일 등 Raw data를 저장하기 위한 방법이다. 폴더와 같은 개념
-
Shared Preference “Key” 와 “Value”로 이루어진 쌍의 값으로서 app에서 user의 preference를 저장할 때 쓴다. 예를 들면 지도 앱에서 거리 단위를 mile로 할 것인지 km으로 할 것인지 지정해 두면 이후 앱이 실행될 때에도 자동으로 이전 저장 preference를 참조할 것이다.
-
Database 아주 많은 량의 데이터를 저장할 때. Related and structured data. 즉 RDB라고 부른다. 여러 개의 논리적으로 나눠진 테이블로 데이타가 저장된다.
SQLite3
프리웨어이며 안드로이드에 기본 탑재되어있는 DB인 SQLite3 사용법을 알아보도록 하겠다. 다운로드 링크는 .. 링크 여기서 windows 32 x86 을 다운받아서, 해당 파일을 C:/sqlite폴더 밑에 풀자. sqlite3.exe파일이 생성될 것이다. 터미널을 통해 명령어를 입력해서 이용할 수 있다.
기본 명령어
C:\sqlite>sqlite3
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
sqlite3
를 통해 db커맨드창에 들어갈 수 있다. sqlite>
로 나타나는 커맨드창에서는 반드시 ;
(세미콜론)으로 명령어를 끝내야 실행됨을 명심하자.
먼저 db파일을 만들어 주자. open
명령어를 이용해 존재하지 않는 db 파일을 만들어 보면 자동으로 생성한다.
sqlite> .open test.db
sqlite>
c:/sqlite폴더에 test.db파일이 생겼을 것이다.
CRUD
db 내 table에서 사용할 수 있는 명령어는 크게 4개의 카테고리로 나뉜다.
-
CREATE : 데이터 생성. 대표 명령어 INSERT INTO
-
READ : 데이터 읽기. SELECT *
-
UPDATE : 기존의 데이터 수정하기
-
DELETE : 기존 데이터 지우기
아래에서 자세히 알아보도록 하자.
SQLite의 자료형
SQLite의 자료형에는 아래와 같이 5개가있다. 아래는 Storage Classes에 속하는 것들이다.
- NULL - 값이 NULL
- INTEGER - 값이 정수
- REAL - 값이 실수
- TEXT - 값이 String
- BLOB - 값이 정확히 우리가 인풋한 값으로 저장(IMAGE나 이진수로 저장 가능)
이제 테이블을 한번 만들어 보자. 다른 언어에서 쉽게 볼 수 있는 boolean이 여기에는 없는데, 쉽게 integer로 대체한다.
테이블 생성 및 제거
db에는 여러 테이블이 있을 수 있다. 테이블 생성 시에는 테이블 명, 컬럼 헤드명과 컬럼에 들어갈 데이터 자료형을 선언해야 한다. 또한 무엇보다 중요한 unique 컬럼, _id
를 포함시키자. CREATE TABLE 명령어로 생성할 수 있다.
아까 생성한 test.db에 접속
C:\sqlite>sqlite3 test.db
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite>
_id
, name
, price
컬럼을 가진 test_table
테이블 생성
.tables
명령어를 통해 확인가능하다.
sqlite> CREATE TABLE test_table(_id INTEGER, name TEXT, price INTEGER);
sqlite> .tables
test_table
sqlite>
.schema
는 어떤 명령어를 통해 table이 생성됐는지 추적할 수 있다.
sqlite> .schema test_table
CREATE TABLE test_table(_id INTEGER, name TEXT, price INTEGER);
PRAGMA TABLE_INFO
를 통해 table값을 직접 볼 수 있다.
sqlite> PRAGMA TABLE_INFO(test_table);
0|_id|INTEGER|0||0
1|name|TEXT|0||0
2|price|INTEGER|0||0
테이블 삭제는 DROP TABLE
이용
sqlite> DROP TABLE test_table;
sqlite> .tables
sqlite> //삭제됨
data 생성 (INSERT)
만들어진 테이블에 데이터를 직접 넣어보도록 하자. 아래와 같은 pets테이블이 있다.
sqlite> PRAGMA TABLE_INFO(pets);
0|_id|INTEGER|0||0
1|name|TEXT|0||0
2|breed|TEXT|0||0
3|gender|INTEGER|0||0
4|weight|INTEGER|0||0
INSERT INTO 명령어를 사용하자.
sqlite> INSERT INTO pets(_id, name, breed, gender, weight)
...> VALUES(1, "Tommy", "Pomeranian", 1, 4);
sqlite> INSERT INTO pets(_id, name, breed, gender, weight)
...> VALUES(2, "Garfield", "Tabby", 1, 8);
.header 를 on / .mode를 column으로 바꾸고 SELECT명령어를 통해 결과를 출력해 보자
sqlite> .mode column
sqlite> .header on
sqlite> SELECT * FROM pets;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
1 Tommy Pomeranian 1 4
2 Garfield Tabby 1 8
데이터 정합성을 위한 Column Constraints
지금까지 테이블을 만들고 데이타를 넣는 법을 배웠다. 하지만 여기엔 작은(?)문제가 있는데… 바로 _id
가 제 역할을 못하고 있다는 점.
_id
컬럼은 분명 unique해야하는데, 새롭게 INSERT INTO 를 이용해 data를 넣으면 중복된 id값이 생겨버릴 것이다. 이를 비롯해 각종 발생할 수 있는 문제점을 사전에 방지할 수 있는 아래 네 가지 커맨드에 대해 알아보자. 아래 키워드는 컬럼 생성 시(CREATE) 덧붙일 수 있는 Constraint 조건이다.
-
PRIMARY KEY : 해당 컬럼은 유니크한 값들로만 구성되어야 한다는 뜻.
-
AUTO INCREMENT : Data INSERT시 아무 값을 넣지 않으면 자동으로 값을 증가시켜서 넣어줌. 주로 PRIMARY KEY 와 함께 쓰임.
-
NOT NULL : 해당 컬럼은 값이 반드시 들어가야 함.
-
DEFAULT
: Data INSERT시 아무 값을 넣지 않으면 자동으로 defalut value가 들어감. 주로 NOT NULL과 함꼐 쓰임.
예시를 통해 알아보자. 다음과 같은 grocery_store db를 만들고 fruits 테이블을 만들자. 이 때 id 컬럼에는 PRIMARY KEY 와 AUTOINCREMENT를, name에는 NOT NULL을, price에는 NOT NULL/DEFAULT 0 커맨드를 추가로 입력했다. 단순히 space로만 구분해서 입력되는 점에 주목.
C:\sqlite>sqlite3 grocery_store.db
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite> CREATE TABLE fuites(
...> _id INTEGER PRIMARY KEY AUTOINCREMENT,
...> name TEXT NOT NULL,
...> price INTEGER NOT NULL DEFAULT 0
...> );
첫 data는 제대로 넣고, 두번쨰 data의 id를 뺴고 넣어보자.
sqlite> INSERT INTO fruits(_id, name, price)
...> VALUES(1, "apple", 100);
sqlite> INSERT INTO fruits(name, price) //id값 누락
...> VALUES("banana", 200);
sqlite> .header on
sqlite> .mode column
sqlite> SELECT * FROM fruits;
_id name price
---------- ---------- ----------
1 apple 100
2 banana 200
sqlite>
자동으로 2가 입력된 것을 볼 수 있다.
id에 원래 있던 값을 넣으려 하면 아래와 같은 unique constraint fail 에러가 난다.
sqlite> INSERT INTO fruits(_id, name, price)
...> VALUES(2, "strewberry", 300);
Error: UNIQUE constraint failed: fruits._id
sqlite>
NOT NULL을 지정해놓은 name 컬럼을 비우고 입력하려면 어떻게 될까? NOT NULL constraint failed 에러가 발생한다. 어떤 컬럼인지까지 나오니까 확인 가능.
sqlite> INSERT INTO fruits(price)
...> VALUES(300);
Error: NOT NULL constraint failed: fruits.name
NOT NULL 이지만 DEFAULT value를 지정해 놨던 price를 비워보면 어떨까? 초기설정값 0과 함꼐 제대로 들어간다.
sqlite> INSERT INTO fruits(name)
...> VALUES("strewberry");
sqlite> SELECT * FROM fruits;
_id name price
---------- ---------- ----------
1 apple 100
2 banana 200
3 strewberry 0
WHERE / ORDER BY
지금까지는 SELECT * 로 전체 값을 항상 봤지만, 데이터베이스의 양이 방대할 때, 원하는 조건의 값들만 선택하고 싶을 때가 있다. 이때 사용하는 것이 WHERE 조건이다.
아래와 같은 명령어를 이용해 pets table을 만들어 보자.
CREATE TABLE pets (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
breed TEXT,
gender INTEGER NOT NULL,
weight INTEGER NOT NULL DEFAULT 0);
INSERT INTO pets (name, breed, gender, weight) VALUES ( "Tommy", "Pomeranian", 1, 4);
INSERT INTO pets (name, breed, gender, weight) VALUES ("Garfield", "Tabby", 1, 14);
INSERT INTO pets (name, breed, gender, weight) VALUES ("Binx", "Bombay", 1, 6);
INSERT INTO pets (name, breed, gender, weight) VALUES ( "Lady", "Cocker Spaniel", 2, 14);
INSERT INTO pets (name, breed, gender, weight) VALUES ("Duke", "Unknown", 1, 70);
INSERT INTO pets (name, breed, gender, weight) VALUES ("Cat", "Tabby", 0, 7);
INSERT INTO pets (name, breed, gender, weight) VALUES ("Baxter", "Border Terrier", 1, 8);
INSERT INTO pets (name, gender, weight) VALUES ("Arlene", 2, 5);
sqlite> .header on
sqlite> .mode column
sqlite> SELECT * FROM pets;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
1 Tommy Pomeranian 1 4
2 Garfield Tabby 1 14
3 Binx Bombay 1 6
4 Lady Cocker Spa 2 14
5 Duke Unknown 1 70
6 Cat Tabby 0 7
7 Baxter Border Ter 1 8
8 Arlene 2 5
WHERE뒤에 각종 조건을 붙여서 원하는 값만 출력할 수 있다.
sqlite> SELECT * FROM pets WHERE _id == 2;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
2 Garfield Tabby 1 14
sqlite> SELECT * FROM pets WHERE weight >= 10;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
2 Garfield Tabby 1 14
4 Lady Cocker Spa 2 14
5 Duke Unknown 1 70
sqlite> SELECT name, breed, gender FROM pets WHERE gender == 1;
name breed gender
---------- ---------- ----------
Tommy Pomeranian 1
Garfield Tabby 1
Binx Bombay 1
Duke Unknown 1
Baxter Border Ter 1
ORDER BY 커맨드를 이용해서는 데이터를 새롭게 정렬할 수 있다. (ASC는 오름차순, DESC는 내림차순)
sqlite> SELECT * FROM pets ORDER BY name ASC;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
8 Arlene 2 5
7 Baxter Border Ter 1 8
3 Binx Bombay 1 6
6 Cat Tabby 0 7
5 Duke Unknown 1 70
2 Garfield Tabby 1 14
4 Lady Cocker Spa 2 14
1 Tommy Pomeranian 1 4
sqlite> SELECT * FROM pets ORDER BY name DESC;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
1 Tommy Pomeranian 1 4
4 Lady Cocker Spa 2 14
2 Garfield Tabby 1 14
5 Duke Unknown 1 70
6 Cat Tabby 0 7
3 Binx Bombay 1 6
7 Baxter Border Ter 1 8
8 Arlene 2 5
data UPDATE
테이블 내 data를 수정하기 위해서는 UPDATE명령어를 사용하자.
형식은 다음과 같다. UPDATE <테이블명> SET <컬럼명 = 원하는값> WHERE <조건을 통한="" ROW선택="">;조건을>테이블명>
sqlite> SELECT * FROM pets ORDER BY name DESC;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
1 Tommy Pomeranian 1 4
4 Lady Cocker Spa 2 14
2 Garfield Tabby 1 14
5 Duke Unknown 1 70
6 Cat Tabby 0 7
3 Binx Bombay 1 6
7 Baxter Border Ter 1 8
8 Arlene 2 5
sqlite> UPDATE pets SET weight = 20 WHERE _id == 1;
sqlite> SELECT * FROM pets ORDER BY name DESC;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
1 Tommy Pomeranian 1 20
4 Lady Cocker Spa 2 14
2 Garfield Tabby 1 14
5 Duke Unknown 1 70
6 Cat Tabby 0 7
3 Binx Bombay 1 6
7 Baxter Border Ter 1 8
8 Arlene 2 5
주의!! WHERE조건을 통해 특정 row를 선택하지 않으면…전체 column 값이 바뀐다.
sqlite> UPDATE pets SET gender = 1;
sqlite> SELECT * FROM pets ORDER BY name DESC;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
1 Tommy Pomeranian 1 20
4 Lady Cocker Spa 1 14
2 Garfield Tabby 1 14
5 Duke Unknown 1 70
6 Cat Tabby 1 7
3 Binx Bombay 1 6
7 Baxter Border Ter 1 8
8 Arlene 1 5
DELETE
DELETE FROM <테이블명> WHERE <조건> 명령을 통해 table내 특정 row의 데이터를 지울 수 있다.조건>테이블명>
매우 주의!! WHERE조건을 통해 row를 특정하지 않을 시 전체 테이블이 날라간다… ……
sqlite> DELETE FROM pets WHERE _id == 4;
sqlite> SELECT * FROM pets;
_id name breed gender weight
---------- ---------- ---------- ---------- ----------
1 Tommy Pomeranian 1 20
2 Garfield Tabby 1 14
3 Binx Bombay 1 6
5 Duke Unknown 1 70
6 Cat Tabby 1 7
7 Baxter Border Ter 1 8
8 Arlene 1 5
댓글남기기