티스토리 툴바


▶ 프로그래밍/DataBase | Posted by Mothrah 2010/07/23 13:30

Sqlite 프로그래밍

Sqlite 프로그래밍

윤상배

                yundream@join.co.kr
            

고친 과정
고침 0.9 2004년 2월 16일 8시
참고문헌및 사이트 추가
고침 0.8 2004년 1월 09일 20시
최초 문서작성

1. 소개

지금까지 Oracle, Mysql, Postgresql 과 같은 큰 규모의 DB프로그래밍을 해왔으며 작은 규모에서 간단하게 사용하기 위한 용도로 gdbm 과 같은 라이브러리를 사용했었다. 이들의 문제는 Oracle, Mysql, Postgresql은 적당한 기능을 지원하기 위해서 지나치게 무겁다는 점이고, gdbm과 같은 경우 매우 가볍고 간단하기는 하지만 기능이 너무 제한적이고 SQL문법을 지원하지 않는다는 점이다. 그러던중 Sqlite를 알게 되었다. 웹프로그래밍도 겸하다보니 좀더 가벼운 DB도구를 찾아 헤메던중 발견했다. 이 문서는 Sqlite의 설치와 프로그래밍 활용방안등에 대한 내용을 담고 있다.

문서는 Linux OS를 기준으로 작성되었다. Windows환경에서의 SQLite의 설치에 대한 힌트를 얻고 싶다면 SWLite Windows를 참고하기 바란다.

또한 SQLite응용 프로젝트도 있으니 이 글을 읽은후 관심이 생겼다면 한번쯤 찾아주길 바란다. SQLiteDBMS 프로젝트로 가기


2. Sqlite

현재 시점에서 최신 버젼인 sqlite-2.8.9를 기준으로 한다.


2.1. Sqlite의 특징

  1. SQL92의 대부분을 지원한다. 다음은 지원하지 않는 몇 가지 기능들이다.

  2. 단일 파일에 데이터베이스의 모든것을 포함한다.

  3. ACID(Atomic, Consistent, Isolate, Durable) 보증

  4. byte order에 관계없이 데이터 파일의 공유가 가능

  5. 2테라바이트 (2^41)크기의 데이터 파일 생성지원

  6. 효율적인 메모리 사용 : 25k라인정도의 C코드로 이루어졌다.

  7. 많은 일반적인 명령을 실행하는데 PostgreSql과 Mysql보다 최소 2배이상 명령에 따라서 10-20배 이상 빠르다.

  8. 하나의 구조체와 3개의 함수만 사용하는 정도로 sqlite를 사용하는 C/C++ 코드를 만들어 낼 수 있다.

  9. TCL, Perl, PHP, .Net, Java, Python, SmallTalk, Ruby등의 다양한 언어지원

  10. 다른 라이브러리등의 도움없이 작동된다. libsqlite.so와 sqlite 2개의 파일이면 작동 환경을 만들 수 있다.

  11. Public Domain 라이센스를 가진다.

  12. sqlite는 서버/클라이언트 모델을 지원하는 RDBMS가 아니다. 로컬에서만 사용가능하며 인터넷응용을 원한다면 별도의 서버 프로그램을 만들어야 한다.


2.2. 설치하기

SQLite 홈페이지에서 다운로드 받을 수 있다. 현재(2003/1/08) sqlite-2.8.9.tar.gz 버젼이 최신버젼이다. 다운로드 받아서 압축까지 풀고 보니 4M정도 되는 작은 크기였다. oracle은 말할 것도 없고 수십메가의 크기를 가지는 postgresql이나 mysql에 비해서도 매우 작은 크기이다.

rpm도 준비되어 있기는 한데, 서버 프로그램들은 무조건 컴파일해서 설치해야 하는 성격이라 tarball을 받아서 컴파일 후 설치하기로 했다. 다음은 필자가 사용중인 리눅스박스의 사양이다.

표 1. 시스템 사양

OS Linux Kernel 2.6.0
컴파일러 gcc 2.96
cpu Intel 800MHZ 업그레이드 시키고 싶다.

설치는 매우 간단하다.

# wget http://www.hwaci.com/sw/sqlite/sqlite-2.8.9.tar.gz
# mv sqlite-2.8.9.tar.gz /usr/src
# tar -xvzf sqlite-2.8.9.tar.gz
# cd sqlite
# ./configure
# make 
# make install
            
옵션없이 설치했을 경우 /usr/local 밑에 자리잡게 된다. 이걸로 설치 끝이다.


3. Sqlite 간단 운용

3.1. DB 생성및 간단한 내부명령어들

sqlite [dbname] 으로 간단하게 생성할 수 있다. 동일한 이름이 존재하면 열고 그렇지 않다면 새로 생성한다.

# sqlite test.db
SQLite version 2.8.9
Enter ".help" for instructions
sqlite> 
            
그다음 부터는 알고 있는 Sql query를 이용해서 필요한 작업을 하면 된다.
sqlite> create table test(name char(80), age int);
sqlite> insert into test values("yundream", 19);
sqlite> insert into test values("hello world", 29);
sqlite> select * from test;
yundream|19
hello world|29
            
내부명령어와 관련된 도움말은 '''.help'''를 입력하는 정도로 간단히 참조할 수 있다.

  1. .databases : 현재 작업중인 DB파일과 관련된 다른 파일들 목록 출력

  2. .echo ON|OFF : 명령어를 반향 할건지 여부

  3. .exit : 프로그램 종료

  4. .help : 도움말

  5. .schema ?TABLE? : 테이블 구조

  6. .show : 현재 프로그램 설정값을 보여준다.

  7. .read FILENAME : FILENAME으로 부터 SQL을 실행한다.

  8. .output FILENAME : 출력을 FILENAME으로 보냄

  9. .output stdout : 출려을 화면으로 보냄(기본 값)

  10. .output stdout : 출려을 화면으로 보냄(기본 값)


4. C/C++ Interface

sqlite는 매우 쉽게 관련 애플리케이션을 제작할 수 있도록 디자인되어 있다. 여기에서는 sqlite C/C++프로그래밍 방법에 대해서 알아 보겠다.


4.1. 핵심 API

sqlite는 3개의 핵심 함수와 하나의 자료구조를 제공한다. 이외에도 몇가지 리턴값과 상수들을 가지고 있다.

typedef struct sqlite sqlite;
#define SQLITE_OK

sqlite *sqlite_open(const char *dbname, int mode, char **errmsg);

void sqlite_close(sqlite *db);

int sqlite_exec
(
  sqlite *db,
  char *sql,
  int (*xCallback)(void*,int,char**,char**),
  void *pArg,
  char **errmsg
);
            
위의 내용만 숙지하는 정도로 C,C++프로그램을 만들 수 있다.


4.2. DB 열기

            sqlite *sqlite_open(const char *dbname, int mode, char **errmsg);
            
sqlite_open 함수를 이용해서 SQLite DB를 열거나 새로운 DB를 생성할 수 있다. 첫번째 인자는 DB이름이다. 두번째 인자는 현재 사용하지 않는다. DB를 여는 중에 에러가 발생한다면 errmsg에 에러메시지를 채우게 된다. 에러가 발생하지 않았다면 NULL을 가리킨다.


4.3. DB닫기

sqlite_close()함수를 호출하면 된다. 인자로는 sqlite_open()으로 생성된 sqlite 구조체 포인터가 들어간다. sqlite_close()를 호출했을 때 트랜잭션(transaction)이 활성화 되어 있는 상태라면 이 트랜잭션은 rolled back 하게 된다.


4.4. SQL 실행

sqlite_exec()를 이용해서 SQL쿼리와 각종 명령을 수행할 수 있다. 이 함수는 5개의 인자를 가진다.

  1. sqlite_open()에 의해서 만들어진 sqlite구조체 포인터다.

  2. sql 쿼리와 sql 명령을 위한 문자열이 들어간다. 이 문자열은 null로 끝난다.

  3. 콜백함수로써 쿼리의 결과를 처리하기 위해서 호출 된다. NULL 이라면 아무일도 하지 않게 된다.

  4. 콜백함수로 넘겨줄 인자의 처음을 가르키는 포인터다.

  5. 에러메시지를 가르키는 포인터다. 이 포인터는 malloc()등을 이용해서 할당된 공간에 씌여지며 함수가 종료되면 free() 된다. NULL이라면 어떤 에러메시지도 보고되지 않을 것이다.

콜백(callback)함수는 쿼리의 결과를 받기 위해서 사용된다. 콜백함수는 다음과 같이 선언되어 있다.

int Callback(void *pArg, int argc, char **argv, char **columnNames))
{
    return 0;
}
            
콜백함수의 첫번째 인자는 sqlite_exec()의 네번째 아규먼트의 복사다. 이 인자는 클라이언트 코드로 부터 콜백함수로 임의의 정보를 전달하기 위해서 사용되어 진다. 두번째 인자는 쿼리결과 생성된 컬럼(columns)의 갯수이다. 세번째 아규먼트는 컬럼의 실제 내용을 담고 있으며 하나의 컬럼 내용은 하나의 배열에 대응한다. 네번째 인자는 컬럼의 이름이다.

콜백함수는 정상적으로 수행되었을 경우 0을 리턴한다. 만약 에러가 발생한다면 0이 아닌 값을 리턴하고 쿼리는 취소된다. 이경우 sqlite_exe()는 SQLITE_ABORT를 리턴할 것이다.


4.5. 에러 코드

정상적으로 실행되었을 경우 sqlite_exec()함수는 SQLITE_OK를 리턴한다. 그렇지 않을경우 다음과 같은 에러 코드들을 리턴한다.

#define SQLITE_OK           0   /* Successful result */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* An internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite_interrupt() */
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* (Internal Only) Table or record not found */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_ROW         100  /* sqlite_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite_step() has finished executing */
            
다음은 각 에러코드들에 대한 설명이다.

SQLITE_OK

명령이 정상적으로 수행되었다.

SQLITE_INTERMAL

SQLite library의 내부적인 문제로 발생하는데, SQLite 라이브러리의 버그에 의해서만 발생된다고 되어 있다. 만약 이 에러가 발생했다면 SQLite mailing list에 문제를 보고하기 바란다.

SQLITE_ERROR

SQL에 문제가 있을 경우 발생된다.

SQLITE_PERM

데이터페이스 파일을 열기위한 권한이 없을 경우 발생한다.

SQLITE_ABORT

콜백함수가 0이 아닌 값을 리턴했을 때 발생한다.

SQLITE_BUSY

다른 프로그램이나 쓰레드가 데이터베이스를 사용하고 있을 때 발생한다. SQLite는 하나의 데이터베이스에 동시에 두개나 그 이상의 쓰레드가 읽는 것을 허용한다. 그러나 쓰기위해서 열었을 경우에는 단지 하나만의 쓰레드만이 접근이 가능하다.

SQLITE_NOMEM

malloc()에 실패했을 때 리턴한다.

SQLITE_READONLY

단지 읽기만 가능한 데이터베이스(혹은 읽기 전용으로 연) 파일에 쓰려고 했을 때 발생한다.

SQLITE_FULL

디스크에 더이상의 공간이 없거나 데어터베이스 파일이 너무나 클경우 발생한다.

SQLITE_AUTH

인증에 실패했다.


4.6. 예제 프로그램

지금까지의 내용들을 이용해서 sqlite 데이터 베이스에 연결해서 데이터를 가져오는 간단한 프로그램을 만들어 보도록 하겠다.

#include <stdio.h>
#include <sqlite.h>

static int callback(void *NU, int argc, char **argv, char **azColName)
{
    int i;
    for (i = 0; i < argc; i++)
    {
        printf ("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}
int main(int argc, char **argv)
{
    sqlite *db;
    char *ErrMsg = 0;
    int rc;

    if (argc != 3)
    {
        fprintf(stderr, "Usge : ./testsql [dbname] [query]\n");
        exit(0);
    }
    db = sqlite_open(argv[1], 0, &ErrMsg);
    if (db == 0)
    {
        fprintf(stderr, "Cant open database ; %s\n", ErrMsg);
        exit(0);
    }
    rc = sqlite_exec(db, argv[2], callback, 0, &ErrMsg);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "SQL error : %d\n", ErrMsg);
    }
    sqlite_close(db);
    return 0;
}
            
프로그램의 이름은 testsql로 하겠다. 다음과 같이 컴파일후 테스트 해보기 바란다.
# gcc -o testsql testsql.c -L/usr/local/lib -lsqlite
            
다음은 테스트 결과다
# ./testsql test.db "select * from test"
name = yundream
age = 19

name = hello
age = 22
# ./testsql test.db "insert into test values(\"kknd\", 56);"
# ./testsql test.db "select * from test"
name = yundream
age = 19

name = hello
age = 22

name = kknd
age = 56
            
고작 38라인 정도로 제대로 작동하는 DB 애플리케이션을 작성했다.


5. 콜백함수를 이용하지 않는 데이터 접근

sqlite_exec() 함수는 SQLite 데이터베이스로 부터 데이터를 가져오기 위한 단지 한 가지 방법만을 제공한다. 방법이 제한되어 있으니 이것 저것 신경스지 않고 간단하게 사용할 수 있겠으나 많은 프로그래머들이 콜백함수를 이용해서 데이터를 가져오는 것에 만족하지 않을 수도 있다. 이런 이유로 SQLite 2.7.7이후 버전에서는 콜백함수가 아닌 다른 방법을 통해서 데이터를 가져올 수 있도록 지원함수를 추가했다.

3개의 새로운 함수가 추가되었는데, sqlite_exec()의 기능을 3개로 나누어서 좀더 세밀하게 제어할 수 있도록 기능을 분할 했다고 보면 된다.

typedef struct sqlite_vm sqlite_vm;      

int sqlite_compile
(
    sqlite *db,          /* 열린 데이터 베이스 */
    const char *zSql,    /* SQL statement to be compiled */ 
    const char **pzTail, /* OUT: uncompiled tail of zSql */ 
    sqlite_vm **ppVm,    /* OUT: the virtual machine to execute zQsql */ 
    char **pzErrmsg      /* OUT: Error message */
);

int sqlite_step
(
    sqlite_vm *pVm,           /* The virtual machine to exeucte */
    int *pN,                  /* OUT: Number of columns in result */ 
    const char ***pazValue,   /* OUT: Column data */ 
    const char ***pszColName  /* OUT: Column names and datatypes */
);

int sqlite_finalize
(
    sqlite_vm *pVm,        /* The virtual machine to be finalized */
    char **pzErrMsg        /* OUT: Error message */
);
        


댓글을 달아 주세요

▶ 프로그래밍/DataBase | Posted by Mothrah 2010/07/23 11:06

SQL Lite

sqlite.gif
초기작성자 - mcguiver9


 

SQLite 는 엄밀히 말해서 DB이지만 DBMS는 아닌 파일DB입니다.


 


 


 

1 특징

  • Transactions are atomic, consistent, isolated, and durable (ACID) even after system crashes and power failures
  • 설치시 setup이나 admin설정이 필요없음
  • 대부분의 SQL92 구현
  • 데이터베이스가 파일 하나로 되어 있음
  • 2테라바이트(2의41승) 지원
  • BLOB과 문자열의 사이즈는 오직 메모리에 의해 제한
  • 실행파일의 사이즈 작음(250KB)
  • Client/Server 데이터베이스 엔진보다 빠른 속도
  • API 갯수가 아주 적음(프로그래밍하기에 간단)
  • 외부 Dependency가 없음
  • public domain 라이센스로 어떤 목적으로도 사용 가능
  • PHP5에서 기본 지원(MySQL 모듈이 빠져있지만 다시 화해했다는 얘기도 있음)

2 3.0에 추가된 기능

  • 향상된 Compact한 데이터베이스 파일 형식
  • 명백한 타입 및 BLOB형식 지원
  • UTF-8, UTF-16 지원 추가
  • 사용자 정의 text collating sequences
  • 64 bit ROWIDs
  • 향상된 Concurrency

3 빠른시작

SQLite라는 DB는 간단히 말해서 SQL을 사용하여 질의할 수 있는 파일DB 이다. DB가 Embeded된 Application을 쉽게 작성할 수 있을 것 같다. 천천히 이 꼬마괴물 DB에 대해서 알아보려 한다.

[http]Quickstart 원문보기

지겨운 메뉴얼부터 보지말고 SQLite를 일단 체험해보자. 여기서는 일단 제가 설치해 본 윈도우버젼을 설명한다.

C:\sqlite> sqlite3 test.db

C++에서의 구현 예제(단, 3개의 함수 제공- 초간단)
#include <stdio.h>
#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}

int main(int argc, char **argv){
  sqlite3 *db;
  char *zErrMsg = 0;
  int rc;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
    exit(1);
  }
  rc = sqlite3_open(argv[1], &db);
  if( rc ){
    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    exit(1);
  }
  rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
  }
  sqlite3_close(db);
  return 0;
}


4 사용가능 문법


  • ALTER TABLE
  • ANALYZE
  • ATTACH DATABASE
  • BEGIN TRANSACTION
  • comment
  • COMMIT TRANSACTION
  • COPY
  • CREATE INDEX
  • CREATE TABLE
  • CREATE TRIGGER
  • CREATE VIEW
  • DELETE
  • DETACH DATABASE
  • DROP INDEX
  • DROP TABLE
  • DROP TRIGGER
  • DROP VIEW
  • END TRANSACTION
  • EXPLAIN
  • expression
  • INSERT
  • ON CONFLICT clause
  • PRAGMA
  • REINDEX
  • REPLACE
  • ROLLBACK TRANSACTION
  • SELECT
  • UPDATE
  • VACUUM

5 사용불가능 문법

아직 SQLite에서는 지원되지 않는 문법

  • FOREIGN KEY constraints
  • Complete trigger support
  • Complete ALTER TABLE support
  • Nested transactions
  • RIGHT and FULL OUTER JOIN
  • Writing to VIEWs
  • GRANT and REVOKE

댓글을 달아 주세요

[쿠키 톡톡] “대중적인 탄산음료 콜라, 이런 용도로 쓰이는 줄 몰랐지?”

각종 순위를 매기는 사이트인 ‘리스트벌스’가 콜라의 뜻밖에 용도 10위를 선정해 최근 발표해 눈길을 끌고 있다. 마시는 건 줄만 알았던 음료수의 새로운 활용법이 흥미롭다.

1. 녹 없애기

콜라는 녹을 제거하는데 효과적이다. 녹이 슨 물건을 콜라에 하루 정도 담가 놓고 나서 잘 비비면 녹이 쉽게 없어진다. 크기가 제법 큰 것들은 콜라를 묻힌 휴지를 붙여두면 된다.

2. 유리창 닦기

콜라의 구연산은 유리창 닦기에도 효과를 발휘한다. 끈적임을 방지하기 위해 콜라 사용 후, 물을 이용해 한 번 더 닦아 주면 좋다.

3. 요리하기

콜라는 여러 가지 요리에도 이용된다. 바비큐 소스와 콜라를 1대 1로 섞어 고기나 생선을 조릴 때 양념장으로 사용하면 좋다.

또 콜라에 담가 둔 닭을 통째로 오븐에 구워도 맛있다. 콜라 당분이 닭고기를 적절하게 입혀져 달콤하다.

4. 스컹크 물리치기

자주 경험할 수 있는 상황은 아니지만 스컹크 악취를 잡는데도 콜라가 쓰인다. 적당량의 세제를 풀은 물통에 콜라 1캔을 더하면 스컹크가 분사하는 냄새를 막을 수 있다.

악취가 몸에 뱄다면 물로 간단하게 샤워를 한 뒤 머리에서부터 발끝까지 콜라를 뿌리고 몇 분 후 다시 닦아내면 효과를 볼 수 있다.

5. 해파리에게 쏘였을 때 응급 처치하기

콜라는 해파리에게 찔렸을 때 약으로도 사용된다. 응급 처치는 간단하다. 해파리에 쏘여 아픈 부위에 콜라를 흘려주면 고통을 없애는데 효과가 있다.

6. 거무튀튀한 냄비를 깨끗하게 하기

냄비를 오래사용하다 보면 바닥에 검은 얼룩이 생긴다. 이렇게 거무스름해진 부분에 콜라를 부은 다음, 약한 불에 끓이고 1시간 정도 놔두면 검은 자국이 사라진다.

7. 세탁하기

양복에 묻은 기름때는 좀처럼 지우기 힘들다. 전용 세제가 있지만 고가다. 이럴 때 콜라를 사용하면 저렴하게 얼룩을 뺄 수 있다.

기름때가 진 옷을 세탁기에 넣고 콜라 1캔을 부은 뒤, 평소와 같이 세탁하면 된다. 혈액을 제거할 때도 유용하다.

8. 벌레 없애기

얕은 그릇에 콜라를 담고 얇은 비닐을 씌워 작은 구멍은 낸다. 그 다음 벌레가 자주 출몰하는 곳에 놓아두면 그릇 안으로 벌레가 모인다. 살충제를 사용하지 않고 한꺼번에 벌레를 없앨 수 있다.

9. 컨디션 개선시키기

속이 울렁거릴 때 콜라 한 잔을 천천히 마시면 그 증상이 사라진다. 또 설사나 인후염에도 콜라가 효과가 있다고 알려져 있다.

10. 콜라 폭탄 만들기

다이어트 콜라에 멘토스(캐러멜의 일종)를 넣자 병 입구를 따라 콜라가 화산처럼 솟아오른다. 이 같은 장면을 온라인 동영상 사이트에서 본 적이 있을 것이다. 화학 반응에 이용한 이 같은 장난은 재미있는 콜라 사용법 중 하나다.

스크랩: http://news.nate.com/view/20100708n12869

댓글을 달아 주세요

<PREV 1 2 3 4 5 ... 24 NEXT>