psql에서 INSERT 문 실행시 한글 문제

postgreSQL의 콘솔인 psql에서 직접 SQL문을 던져서 테이블을 생성하고 데이터를 INSERT할때 한글 데이터에서 INSERT 문의 실행 조차 되지 않는 문제는 postgreSQL에 대한 서버 측과 클라이언트 측의 한글 처리 방식(인코딩)이 다르기 때문입니다. 만약 서버 측의 인코딩 방식이 UTF8이라면 클라이언트 측의 인코딩도 UTF8로 변경해야 합니다. 방법은 콘솔에서 다음처럼 입력하면 됩니다.

set client_encoding = 'UTF8';

이렇게 하고 한글 데이터를 가진 INSERT 문을 실행하면 잘들어갑니다. 그리고 SELECT 문을 통해 확인해 보면 제대로……. 가 아닌 한글이 깨져 보입니다.

사용자 삽입 이미지
뭐가 문제인지 기본으로 돌아가 생각해보면… 먼저 psql 콘솔에서 SQL 문은 외부 파일을 통해 다음처럼 실행합니다.

\i c:/insert.sql

그런데 이 insert.sql 파일은 C#으로 만든 것이고.. 혹시 C#에서 이 파일을 생성할 때 인코딩 지정 문제로 생각하여 UTF8로도 해보고 EUC-KR로도 인코딩 해보았으나 모두 깨지고.. 여차 저차 결국 인코딩 없이(그럼 이건 어떤 인코딩이지?) 그냥 저장하도록 다시 원복하고 GUI 툴인 pgAdmin에서 해당 데이터를 보니 한글이 않깨져 있습니다.
사용자 삽입 이미지
결론은 한글이 제대로 저장된 것이고 콘솔에서 한글이 깨져 표시되는 것이였습니다. 일단 Windows에서는 한글 데이터 저장은 되었는데.. 실제 구동은 리눅스에서 하는데 거기에도 또 다른 한글 문제가 흐물 흐물 기다리고 있을 듯 한데.. 걱정입니다.. 일단 작업은 Windows에서 하고.. 최종 배포에서 나타날 한글 괴물 보스에게 빌어야 겠네요…

참고로 psql의 출력결과를 파일로 내보내기 위해서 다음 명령을 수행하면 됩니다.

\o c:/log.txt

이때 psql을 관리자 권한으로 실행해야 합니다.

반복문의 반복 횟수를 줄이는 코드 작성

반복문의 속도를 최적화하기 위한 방법중의 하나로 반복 횟수를 줄이는 것이 있습니다. 이에 대해서 제프 그린버그(Jeff Greenberg)가 제안한 내용이 있는데요. 처음 제안될때 작성된 샘플 코드가 C이지만 이를 JavaScript로 해석해 보았습니다. 먼저 개선해 나갈 반복문의 코드가 다음과 같습니다.

function task(arg) {
    var sum = 0;
    for (var i = 0; i < 10; i++) {
        sum += i;
    }
    return sum;
}

var start = +new Date();
var result = 0;
var repeatCounts = 9999999;

//========================================
for (var i = 0; i < repeatCounts; i++) {
    result += task(i);
}
//========================================

var end = +new Date();
var diff = end - start;
alert("result = " + result + ", " + diff + " msec");

최적화 대상이 되는 반복문은 13ㅡ17번입니다. 반복문 안에서 실해된 코드를 별도의 함수인 task로 뽑아놨습니다. task는 1부터 10까지의 합계를 구하는 간단한 연산을 수행하는 함수입니다. 반복문의 속도를 측정하기 위해서 반복문 앞뒤로 시간을 측정하고 있습니다. 이 반복문을 수행하였더니 제 타블릿PC에서는 8.6초가 나왔습니다. 이제 동일한 결과를 얻으면서도 반복 회수를 줄이는 방식으로 최적화를 한 코드는 다음과 같습니다. 위의 13ㅡ17번에 대한 반복 코드에 대한 변경된 부분만 언급하였습니다.

//========================================
var iters = Math.floor(repeatCounts / 10);
var startAt = repeatCounts % 10;
var i = 0;

do {
    switch (startAt) {
        case 0: result += task(i++);
        case 9: result += task(i++);
        case 8: result += task(i++);
        case 7: result += task(i++);
        case 6: result += task(i++);
        case 5: result += task(i++);
        case 4: result += task(i++);
        case 3: result += task(i++);
        case 2: result += task(i++);
        case 1: result += task(i++);
    }
    startAt = 0;
} while (iters--);
//====================================

한번의 반복으로 최대 10번의 반복을 대신하고 있습니다. switch 문을 보면 break문이 없다는 점을 유념해 해석해 보면 그 원리를 이해할 수 있습니다. 실행해 보면 소요되는 시간이 6.3초로 2.4초 단축된 것을 알 수 있습니다.

HTML&CSS3 양용석 지음, 로드북 출판

HTML5에는 다양한 새로운 기술들이 제공되는데.. 이 책은 그 중에서 HTML5에서 새롭게 추가된 HTML Tag에 대해 상세히 설명하고 있습니다. CSS3에 대해서는 기본적인 내용만을 다루고 있습니다. HTML5와 CSS3에 대해서 매우 화려하지도 않은, 또한 매우 깊은 곳은 다루지 않으나 기 기본적인 내용이 왜(Why) 존재하는지 잘 설명되어 있는 책이라고 생각합니다. 특히 책 후반의 실제 웹 표준 사이트를 밑바닦부터 완전히 새롭게 구축해 나가는 내용은 매우 훌룡합니다.

사용자 삽입 이미지
 기존에 HMTL과 CSS를 알고 있다면 HTML5와 CSS3에 대해서 이 책을 통해 중요한 기본적인 내용을 살펴보고 실제로 웹 사이트를 만들어 보는 실습을 통해 더욱 깊이 있게 학습할 수 있는 책이라고 생각합니다. 저는 실습 부분에 대해서 2번 해 봤는데.. 처음할때는 실수가 많았으나 두번째에는 무난하게 진행할 수 있었습니다.

CSV 포맷(Format)의 문자열(String) 파싱(Parse, Parsing)

CSV 형태로 된 문자열을 파싱하기 위한 C#언어로 작성된 함수입니다. 예전에 XrGeocoder 프로그램을 개발할때 사용했던 함수로.. 또 다른 프로젝트에서 사용되면서 함수만을 분리해 정리해 봅니다.>/p>

private List SeperateStringWithComma(String value)
{
    bool inQuotes = false;
    char delim = ',';
    List strings = new List();

    StringBuilder sb = new StringBuilder();
    foreach (char c in value)
    {
        if (c == '\'' || c == '"')
        {
            if (!inQuotes)
                inQuotes = true;
            else
                inQuotes = false;
        }

        if (c == delim)
        {
            if (!inQuotes)
            {
                strings.Add(sb.Replace("'", string.Empty).Replace("\"", string.Empty).ToString());
                sb.Remove(0, sb.Length);
            }
            else
            {
                sb.Append(c);
            }
        }
        else
        {
            sb.Append(c);
        }
    }

    strings.Add(sb.Replace("'", string.Empty).Replace("\"", string.Empty).ToString());
    return strings;
}

위의 함수를 사용하는 예제는 다음과 같습니다.

String csv = "2011-01-01,18,2008,개인,인천,중구,~,2010-12-31,233400,남자";
List values = SeperateStringWithComma(csv);

int cntValues = values.Count;
for (int i = 0; i < cntValues; i++)
{
    MessageBox.Show(values[i]);
}

Flex에서 Timeline 애니메이션 주기

greenshock의 tween 라이브러리를 사용하여 타임라인 애니메이션을 주는 것에 대해 살펴보았습니다. 요즘 UI 디자인의 추세가 정적인 부분에서는 최대한 Simple하게.. 대신 동적인 효과를 주는 것이기에 추후 고객에게 제공할 시스템에서 적용해볼 요량으로 학습하여 정리해봅니다.

원하는 효과는 다음과 같습니다. 사각형 버튼을 0.4초간 수평으로 화면의 가로 가운데로 이동하고 다시 0.4초간 수직으로 화면의 세로 가운데로 이동한 뒤.. 끝으로 0.3초간 2배 확대하는 애니메이션입니다.

사용자 삽입 이미지
이에 대한 코드는 다음과 같습니다.

TweenPlugin.activate([TransformMatrixPlugin, BezierPlugin]); // 1번만 호출하면 됨

var myTimeline:TimelineLite = new TimelineLite({paused:true}); 
var w:Number = btn.width;
var h:Number = btn.height;

// 화면 중심 이동 및 확대를 위해 화면 크기(300, 300)의 반절값인 150 사용 
myTimeline.append(new TweenLite(btn, 0.4, {x:150-w/2})); 
myTimeline.append(new TweenLite(btn, 0.4, {y:150-h/2}));
myTimeline.append(
    new TweenMax(btn, 0.3, {transformMatrix:{tx:150-w,ty:150-h,scaleX:2, scaleY:2}})
);

myTimeline.play();

간단하게는 사용자 경험(UX)는 사용자에게 사용자 인터페이스(UI)와 동일하게 생각할 수 있습니다. 최근 Windows 8이나 Apple의 iOS의 UI를 살펴보면 과거 입체적인 UI에서 벗어나 보다 평면적인 UI로 디자인되어 있는 것을 볼 수 있습니다. 그러나 이 평면적인 UI에 사용자가 반응을 하게 되면 마치 생명체처럼 움직여 반응하게 됩니다.

UI 및 UX를 가장 효과적으로 학습하는 방법은 이러한 OS의 UI를 살펴보고 사용해 보는 것이 가장 좋다고 생각합니다. 개발자나 디자이너라면.. 이러한 사용에서 끝나는 것이 아니라 자신이 만드는 창작물에도 이러한 배움을 반영해 보는 것이 의미있는 일이라 생각합니다.