안드로이드는 데이터베이스로 SQLite3를 사용한다.
sqlite3 은 가볍게 사용할 수 있어 임베디드에서 많이 사용하는 오픈소스 데이터베이스 엔진이다.

프로젝트에서 DB가 필요한데 sqlite 에 직접 insert하기 귀찮아 스크립트로 sql을 생성했더니 sqlite3에 넣을 방법이 필요했다. 노가다로 붙여넣기 신공을 사용하려 했으나 아주 간단하게 처리가 가능했다.

linux만을 전제한다.

1) sql 명령어 set으로 backup받는 경우

echo ".dump" | sqlite3 mydb.db > backup.script

2) sql 명령어 집합으로 db 파일 만들기

sqlite3 < backup.script


(backup.script는 SQL로 이루어진 text 파일이다)
허접한 글이지만, 도움이 되신다면 아래 손가락 꾹 눌러주세요.
Posted by 소혼

댓글을 달아 주세요

자바에도 String.format이 있구나.
printf와 유사하다.

String temp = String.format("%03d_%d", lec, parts);
와 같이 쓴다.

두 변수의 값이 1 2 즉, lec이 1 parts가 2라면
String temp = "001_2 "
과 같이 된다.

'프로그래밍 언어 > <Java>' 카테고리의 다른 글

Sort a HashMap by Value  (0) 2011.08.07
JNI on linux  (1) 2010.12.27
[자바] 날짜, 요일 출력.  (0) 2010.11.06
[자바]일련의 숫자 임의 정렬하기  (0) 2010.07.31
[String]String.format  (0) 2010.06.16
[팁] File 읽어서 파싱하기  (0) 2010.06.10
Posted by 소혼
TAG 자바

댓글을 달아 주세요

1. File을 new line 단위로 읽기

        InputStream fis = myResources.openRawResource(resource 명)
        InputStreamReader isr = new InputStreamReader(fis);

        BufferedReader br = new BufferedReader(isr);

        try {
            String line = br.readLine();
            Log.w("ENGLISH1", line);
        } catch (IOException e) {
            e.printStackTrace();
        }

2. 특정 delimeter 단위로 읽기
        InputStream fis = myResources.openRawResource(R.raw.myfile); // 안드로이드 코드
        Scanner scn = new Scanner(fis).useDelimiter("\\r");

        String parsedStr, parsedStr2;
        while (scn.hasNext()) {
            parsedStr = scn.next();
        }

몇개의 delimeter를 섞어 쓰려면 
ex) "\\r|," <- ^M 또는 , 단위로 구분

'프로그래밍 언어 > <Java>' 카테고리의 다른 글

Sort a HashMap by Value  (0) 2011.08.07
JNI on linux  (1) 2010.12.27
[자바] 날짜, 요일 출력.  (0) 2010.11.06
[자바]일련의 숫자 임의 정렬하기  (0) 2010.07.31
[String]String.format  (0) 2010.06.16
[팁] File 읽어서 파싱하기  (0) 2010.06.10
Posted by 소혼
TAG 자바

댓글을 달아 주세요

C++에서 static을 다소 헷갈리게 만드는 요소가 있긴 하지만,

header에서 static 변수를 선언해서는 안된다.

static : 지역 변수임을 알려주는 키워드 (C++ 클래스 내부의 static과 다른 의미이다.)

헤더에서 static을 선언하면 어떤 일이 일어날까?
간단한 예제를 만들어보았다. (컴파일 없이 손코딩했음)


common.h
static int gvalue = 10;


main.c
#include <stdio.h>
#include "common.h"
#include "b.h"

int main () {
    printf("%d\n", gvalue);
    call_b();
    printf("%d\n", gvalue);
    return 0;
}

b.h
void call_b();

b.c
#include "common.h"

void call_b() {
    gvalue++;
}

간단한 예제인데, 이 때 출력되는 값은 얼마일까?
10과 11이 출력되길 기대하겠지만 안타깝게도 10과 10이 출력이 된다.
이유는 gvalue가 main.c와 b.c에 각각 따로 존재하기 때문이다.
nm으로 바이너리를 까보면 gvalue를 위해 두개의 심볼이 존재하는 것을 알 수 있다.
즉, b.c가 증가시킨 gvalue는 main.c에 보이지 않는 b.c를 위한 지역변수가 된다.

그럼 이런 실수를 왜 할까?
C++로 넘어오면서 일부 책에서 #define을 쓰지 말고 const를 쓸것을 권장하고 있다. 이러한 상수형(?) 변수를 쓰는 것이 debugging에 도움이 될 수 있고 그다지 성능을 많이 잡아먹지 않을 것이라는 것은 안다.(제대로 짰을때에 한해서)
이렇게 만들어진 const를 그냥 header에 넣으면 분명 에러가 발생한다. 이유는 헤더가 동일한 상수형 변수를 여기저기 만들기 때문이다.운
거기서 포기하지 않고 static을 붙이면 컴파일은 되겠지만, 나중에는 찾기 어려운 재앙이 될 수 있다.

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

__builtin_expect 키워드  (0) 2010.09.10
gcc 업그레이드 (4.5.0)  (0) 2010.07.21
Header안에 static 변수  (0) 2010.02.21
디버깅하는 법 - 툴 - ltrace  (0) 2010.02.18
unresolved symbol 에 관하여  (0) 2010.01.27
[Python]파일명 바꾸기  (0) 2009.09.02
Posted by 소혼
TAG C, C++

댓글을 달아 주세요

디버깅이란 말 그대로 버그를 잡는다는 뜻이다.

코딩을 잘하는 사람이 대체로 디버깅도 잘하는 법이지만, 아무래도 디버깅을 유별나게 잘하는 사람들이 있다.
또, 디버깅 실력은 사람의 실력도 중요하지만 그가 사용하는 툴의 능력도 결코 무시할 수 없는 것 같다.

Visual C++이나, Eclipse같은 툴을 쓸 수 있다면야 참 좋겠지만,
아무래도 임베디드 환경에서 이런 호사는 기대하기 힘들고
심지어 gdb마저도 쓰기 힘든 경우가 많다.

이럴 때 strace, ltrace를 사용해보는 것도 좋을 듯 싶다.
지금까지 gdb없으면 디버깅 못한다고 짧은 생각을 해왔는데 ltrace를 보니 때론gdb보다 뛰어나다는 생각마저 든다.

ltrace 는 라이브러리상에 호출되는 symbol들의 이름을 출력해준다.
콜 스택을 보여주진 못하지만, API들이 순차적으로 호출되는 흐름을 보여주기 때문에
만약 비정상적인 동작을 할 때,
또는 이상하게 시간이 많이 걸릴 때
문제를 추적하는데 도움을 줄 수 있다.

물론 함수콜만을 보여주기 때문에 특정 함수 내부에서 일어나는 코드들을 보장못하지만 코드의 흐름을 분석하고 이해하는데 큰 도움이 된다.

또, 해당 함수를 수행하는데 걸린 시간을 출력할 수 있어서, 전체적인 수행시간에 어떤 부분이 많은 시간을 잡아먹는지 분석도 가능하다.

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

gcc 업그레이드 (4.5.0)  (0) 2010.07.21
Header안에 static 변수  (0) 2010.02.21
디버깅하는 법 - 툴 - ltrace  (0) 2010.02.18
unresolved symbol 에 관하여  (0) 2010.01.27
[Python]파일명 바꾸기  (0) 2009.09.02
AspectC++  (0) 2009.08.31
Posted by 소혼

댓글을 달아 주세요

컴파일(정확히는 링크)을 할 때 아래와 같은 에러를 종종 보곤 한다.
unresolved symbol이라는 에러는 말 그대로 해당 심볼명을 찾을 수 없다는 에러이다.

이런 에러가 났을 때, 우리가 해야 할 일은

[ 내가 만든 함수인 경우 ]
   1. unresolved symbol이 뜬 곳에서 함수명, 인자의 타입, 개수, 반환값등을 확인한다.
   2. 해당 함수를 포함한 파일이 컴파일 되는지 확인한다.
      매크로등에 의해 컴파일에 포함되지 않을 수도 있기 때문이다.
      쉽게 확인하는 방법의 하나는 해당 함수에 #error를 넣고 컴파일해보는 것이다.
      컴파일 에러가 아니라, unresolved symbol이 또 뜬다면, 그 함수는 컴파일에 포함되지 않은것이다.
  3. C함수인지 C++함수인지 확인한다.
      C++로 컴파일 할 때, C함수(C로 컴파일되는 파일에 있는 함수)를 처리하려면 헤더파일에는 extern "C" { }안에 함수가 선언되어 있어야 한다.
      만약 헤더파일에서 이러한 처리가 제대로 안되어 있다면 C++은 해당 함수의 이름을 C++형태로 추적하려 한다.

[ 남이 만든 함수인 경우(라이브러리에서 참조하는 경우) ]
   4. 3번과 같이 헤더파일에 제대로 선언되어 있는지 확인한다.
   5. 라이브러리 파일안에 해당 함수가 있는지 파일 내부를 검색한다.(grep같은 것을 이용하여)
   6. 컴파일 할 때, 해당 라이브러리가 포함되는지 확인한다.
       리눅스의 경우 -L의 라이브러리의 경로가 맞게 포함되어 있는지, -l로 해당 라이브러리가 첨부되어 있는지 확인해야 한다.

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

gcc 업그레이드 (4.5.0)  (0) 2010.07.21
Header안에 static 변수  (0) 2010.02.21
디버깅하는 법 - 툴 - ltrace  (0) 2010.02.18
unresolved symbol 에 관하여  (0) 2010.01.27
[Python]파일명 바꾸기  (0) 2009.09.02
AspectC++  (0) 2009.08.31
Posted by 소혼

댓글을 달아 주세요


<B Tree Index - www.filibeto.org/sun/lib/nonsun/...t169.gif 발췌>

오랜만에 DB를 만지게 되었다.
sqlite3의 내부 구조를 모르지만, File DB라고 들었는데 성능을 위한 옵션 같은것이 분명 존재할 것 같다.

어쨌거나 모바일에서 테이블 한두개 만드는데 문제가 되겠냐만, 옛날 DB 공부할 때 생각에 Primary Key를 Natural Key로 할 지, Surrogate Key로 할지에 대해 고민해봤다.

생각보다 입맛에 딱 맞는 자료를 못찾아 그냥 내 맘데로 생각을 풀어본다.

먼저 자연키가 무엇이고 대체키가 무엇인지부터 정리해보기로 한다.
기본키 ( Primary Key ) : 테이블에서 레코드를 유일하게 식별하는 데 가장 적합한 후보키(Candidate Key)
자연키 ( Natural Key ) : 테이블을 이루는 컬럼들 가운데 의미를 담고 있는 후보키
대체키 ( Surrogate Key ) : 테이블을 이루는 컬럼들 가운데 유일하게 식별하기에 적합한 단일 후보키가 존재하지 않을 때, 임의의 식별번호로 이루어진 후보키를 추가할 수 있는데 이를 대체키라고 한다.

Primary Key는 두가지 특성을 가지고 있다고 생각한다.
< 제약과 인덱스 >

제약은 원래 관심사항이 아니었고, 인덱스가 중요하다고 생각한다.
Primary Key는 일반적으로 인덱스를 구축한다. 심지어 SQL Server의 경우는 Cluster Index가 되기도 한다.
인덱스가 검색을 위한 것이기 때문에 검색에서 핵심이 되는 값이 Primary Key가 될수록 성능에 지대한 공헌을 하게 된다.

일반적으로 대체키의 도입을 고민하는 경우는, 자연키가 숫자로 이루어지지 않는 경우이다.
만약 자연키가 숫자로 있다면 당연히 대체키를 도입할 필요가 없다.

만약 자연키가 문자열이거나 하나 이상의 컬럼을 결합키로 만드어야 한다면 우리는 대체키를 도입할 것인가 고민해보아야 한다.
이것은 단순히 어느쪽이 좋다라고 할 수 있는 문제는 아닌 것 같다.

integer index와 문자열 인덱스의 성능은 당연히 integer index가 빠르다.
따라서 일반적인 경우 대체키를 사용하는 것이 낫다. 검색의 성능도 빠르고 크기도 작기 때문에 Block IO도 적게 발생할 가능성이 높다.

자연키는 그 자체가 의미를 갖는 검색이 될 수 있지만, 대체키는 레코드의 기본키를 이용한 수정, 삭제, 외래키 참조에만 효율적이다.
자연키는 자신이 정보를 가지고 있으므로, 테이블에서 자연키로 검색하는 경우가 대부분이고 수정, 삭제, 외래키 참조가 없다면 자연키를 인덱스로 사용하는 것이 낫다.
만약 둘 다 빈번하면 자연키를 사용하는 인덱스를 하나 더 만드는 것도 고려할 수 있을 것 같다.
그러나 범위검색의 가능성이 큰 자연키에게 클러스터나 클러스터드 인덱스는 양보하는 편이 좋을 것 같다.

대체키는 대체키를 생성하기 위한 트릭이 필요하다.
Oracle 의 Sequence나 auto increment가 전혀 비용을 수반하지 않는다고 생각하지 않는다. 하지만 입력할때 인덱스를 구축하는 비용은 문자열 인덱스가 클 것 같다. 어쨌거나 위에 언급한 것 같은 시스템이 지원하는 방법이 없어서 SELECT를 한번 더 사용해야 하는 DB의 경우라면 대체키 도입은 좋은 방법이 아닐 수 있다. 물론 검색이 더 중요한 경우가 대부분이므로 입력의 비용은 무시하고 생각할 수도 있을듯 하다.

정리하고자 적어봤는데
결국 뭘 어떻게 하라는 건지
어쨌든 대부분의 경우는 대체키가 좋지 않을까 조심스레 생각해본다.



Posted by 소혼

댓글을 달아 주세요

  1. 나그네 2015.08.07 00:43 Address Modify/Delete Reply

    자택야근(?)중 우연히 좋은 글을 보게 되어 감사하게 생각합니다. 그런데, 글 말미에 '결국 뭘 어떻게 하라는 건지' 라고 하셨는데, 사실 DB는 우리에게 뭘 어떻게 하라고 절대 강요하지 않습니다. 오히려 구축해야 할 시스템이 '뭘 어떻게 하라'고 강요할 뿐이죠. 즉, 상황에 따라 성능이 우월해 보이는 키/인덱스를 도입해서 쓰면 되겠죠. 상황이 바뀌면? 뭐 어차피 다시 설계하고 다시 코딩해야 하는거죠 뭐ㅡ.ㅡ (코딩변경 최소화 하면서 DB문제 해결하는분이 최고!). 그리고 성능문제는 시스템이 몇일~몇달~몇년 굴러가 봐야 제대로 파악되는 것이므로 그때가서 해결하는게 정신건강에 이로울것 같습니다^^ 그렇다고 해도 아무것도 모르는 사람이 만든 DB를 손봐야 하는 괴로움은 좀 없어야 겠죠ㅎㅎ
    오랜만에 실무에 빠져버린 개발자였습니다. 혹시 저와의 소통에 관심이 있으시면 metalgods74@hotmail.com으로 메일 주세요~

    • 소혼 2015.08.10 10:21 신고 Address Modify/Delete

      댓글 감사합니다.
      5년이 지난 지금, 데이터베이스쪽 분야에 있진 않아서 이쪽 세상을 잘 따라가고 있진 못합니다.
      (한때는 DBA가 되고 싶었는데 말이죠 ㅎㅎ)

      이런 고민이 아직도 필요한가하는 의구심은 있지만, 말씀하신것처럼 DB에 대한 고민을 조금이라도 더 해본 분들이 DB를 만지는게 좋을듯 합니다.

      전 이미 커리어가 산으로 ( '');


예섬이를 위해 간단히 짜본 파이썬 스크립트.
문제는 엠파스에서 탭이 제대로 안붙는구나 ;;
[요구사항]
특정 폴더를 선택하여, 해당 폴더가 가지고 있는 파일들의 이름 앞에 특정 문자열을 붙일 수 있어야 한다.
import os, time, string
from Tkinter import *
from tkFileDialog import askdirectory

top = Tk()
F = Frame(top)
F.pack(expand="true")

myPath = askdirectory(title="select directory", mustexist=1)
if not myPath:
	os.exit
else:
	print "selected", myPath

#myPath = raw_input("Enter the path you want to change filename : ");
suffix = raw_input("Input suffix you want : ");
for f in os.listdir(myPath):
	tempPath = os.path.join(myPath, f)
	tempPath2 = os.path.join(myPath, suffix + f)
	if not os.path.isdir(tempPath):
		os.rename(tempPath, tempPath2)

raw_input("finished")

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

gcc 업그레이드 (4.5.0)  (0) 2010.07.21
Header안에 static 변수  (0) 2010.02.21
디버깅하는 법 - 툴 - ltrace  (0) 2010.02.18
unresolved symbol 에 관하여  (0) 2010.01.27
[Python]파일명 바꾸기  (0) 2009.09.02
AspectC++  (0) 2009.08.31
Posted by 소혼
TAG Python

댓글을 달아 주세요


http://ddkkfj.tistory.com/trackback/3
http://heestory.kr/trackback/320
http://www.zdnet.co.kr/ArticleView.asp?artice_id=00000039147106
http://www.aspectc.org/

오랜만에 서핑을 하니 읽어야 할게 많네..

옛날 AspectJ 보고 부러워 했는데 C++도 역시 있었군

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

gcc 업그레이드 (4.5.0)  (0) 2010.07.21
Header안에 static 변수  (0) 2010.02.21
디버깅하는 법 - 툴 - ltrace  (0) 2010.02.18
unresolved symbol 에 관하여  (0) 2010.01.27
[Python]파일명 바꾸기  (0) 2009.09.02
AspectC++  (0) 2009.08.31
Posted by 소혼
TAG AspectC++

댓글을 달아 주세요