암호화 기본 내용

AES는 암호화 복호화 과정에서 동일한 키를 사용하는 대칭 키 알고리즘이다.

 

대칭 키 암호는 암호화 알고리즘의 한 종류로, 암호화와 복호화에 같은 암호 키를 쓰는 알고리즘을 의미한다.

대칭 키 암호에서는 암호화를 하는 측과 복호화를 하는 측이 같은 암호 키를 공유해야 한다. 이러한 점은 공개 키 암호에서 공개 키와 비밀 키를 별도로 가지는 것과 구별된다. 대신, 대부분의 대칭 키 암호는 공개 키 암호화 비교하여 계산 속도가 빠르다는 장점을 가진다

 

대칭 키 암호는 암호화하는 단위에 따라 스트림 암호화 블록 암호로 나눌 수 있다.

-       스트림 암호는 연속적인 비트/바이트를 계속해서 입력 받아, 그에 대응하는 암호화 비트/바이트를 생성하는 방식이다.

-       블록 암호는 정해진 한 단위(블록)를 입력 받아 그에 대응하는 암호화 블록을 생성하는 방식이다.

 

DES AES가 블록 암호의 대표적 알고리즘이다.

 

블록 암호는 암호화할 때 블록을 어떻게 사용하느냐에 따라 4가지의 모드로 나눠진다

 

-       ECB(Electric CodeBook)

-       CBC(Cipher Block Chaining)

-       CFB(Cipher FeedBack)

-       OFB(Output FeedBack)

 

블록 암호에서 중요한 것은 암호화할 평문을 일정 길이의 블록으로 나눈다는 것이다.

만약 평문이 일정 길이의 블록으로 나눠지지 않는다면 ‘패딩(padding’이라고 하는 빈 데이터를 마지막에 덧붙인다그리고 나눠진 각각의 블록을 하나씩 키로 암호화한 후 생성된 암호 블록들을 하나로 합친다. 끝으로 패딩은 제거한다

 

CBC 모드는 XOR 연산 과정이 추가된 것이다. CBC 모드에서는 블록의 XOR 연산을 하기 때문에 초기 연산 블록으로 사용되는 IV(initiation Vector)가 필요하다.

IV는 블록 중의 하나를 선택하거나 블록 길이와 같은 길이의 임의의 데이터를 사용한다

 

 

키는 고정하고

Iv의 값을 같이 보내서 서버에서 복호화할 수 있게 해야 한다

라이브러리 사용 시 프로젝트 속성 설정

  1. 추가 포함 디렉터리
Include 할 헤더 파일이 있는 디렉터리를 지정한다.
ex)  Opencv 라이브러리의 경우 각 프로젝트마다 opencv 헤더파일을 가지고 있는 것이 아니라,

특정 위치(c:\opencv) opencv 관련 라이브러리가 있고, 사용할 프로젝트에서 해당 디렉토리 위치를 추가하여 헤더파일을 읽어 사용한다




추가 포함 디렉토리를 등록하면 아래와 같이 바로 헤더 파일 디렉터리를 가져온다





2. 추가 라이브러리 디렉터리


  사용할 lib 파일이 있는 디렉터리를 지정한다. 헤더파일과 마찬가지로 링커>입력>추가 종속성에서 lib 파일을 지정할 경우 해당하는 디렉터리에서도 lib 파일 유무를 확인한다





3. 추가 종속성


실제 사용할 라이브러리 파일의 이름을 적어준다

속성페이지에서 아래와 같이 lib 파일을 지정할 수 있고, #pragma (lib, opencv_calib3d2411d) 와 같이 코드에서 명시적으로 사용 라이브러리를 지정할 수 있다






'and so on' 카테고리의 다른 글

암호화 기본 내용  (1) 2015.04.23
[windbg] kb 명령어  (0) 2015.03.05
chapter01. 네트워크 프로그래밍과 소켓의 이해  (0) 2014.12.09
상속 vs 포함 (포함 예제)  (0) 2014.12.03
상속 vs 포함  (0) 2014.12.03

[LNK2019] 확인할 수 없는 외부 참조입니다.

openCV 사용하다가 lnk2019에러 발생하였다.

맨 처음에는 라이브러리 참조에서 발생한걸로 당연히 알고 

참조 라이브러리 오타 확인하고 또 하고 했는데



"void __stdcall cv::error(class cv::Exception const &)" (?error@cv@@YGXABVException@1@@Z) 외부 기호(참조 위치: "public: class cv::Vec<unsigned char,3> & __thiscall cv::Mat::at<class cv::Vec<unsigned char,3> >(int,int)" (??$at@V?$Vec@E$02@cv@@@Mat@cv@@QAEAAV?$Vec@E$02@1@HH@Z) 함수)에서 확인하지 못했습니다.

"void __stdcall cv::fastFree(void *)" (?fastFree@cv@@YGXPAX@Z) 외부 기호(참조 위치: "public: __thiscall cv::Mat::~Mat(void)" (??1Mat@cv@@QAE@XZ) 함수)에서 확인하지 못했습니다.

"int __stdcall cv::_interlockedExchangeAdd(int *,int)" (?_interlockedExchangeAdd@cv@@YGHPAHH@Z) 외부 기호(참조 위치: "public: __thiscall cv::Mat::Mat(class cv::Mat const &)" (??0Mat@cv@@QAE@ABV01@@Z) 함수)에서 확인하지 못했습니다.



호출 규칙이 _stdcall(/Gz)로 되어 있었다


__cdecl(/Gd)로 변경하여 해결



[windbg] kb 명령어

ecxr : 예외가 발생한 context로 변경

Kb : call stack 출력

ð  .ecxr을한 후 kb를 수행할 경우 예외가 발생하기까지의 call stack을 출력한다

~[스래드번호]s  : [스레드번호]로 컨텍스트 변경 (ex ~0s 0번째 스레드로 이동

ð  스레드로 이동 후 kb를 수행할 경우 예외 발생 이후의 call stack을 출력한다.

 

[error D8016] '/ZI'과(와) '/GL' 명령줄 옵션이 호환되지 않습니다.

 

 

명령줄에 /GL /ZI 옵션이 같이 들어가 있다

 

속성 변경

 

 

변경 후 명령 줄

 

 

/GL 옵션이 사라짐

 

참고

https://msdn.microsoft.com/ko-kr/library/xbf3tbeh.aspx

 

Visual Studio 개발 환경에서 이 컴파일러 옵션을 설정하려면

 

1. 프로젝트 속성 페이지 대화 상자를 엽니다.  프로젝트 속성 사용 를 참조하십시오.

2. 구성 속성 폴더를 선택합니다. 

3. 일반 속성 페이지를 클릭합니다. 

4. 전체 프로그램 최적화  속성을 수정합니다.

 

 

 

 

 

'and so on > error' 카테고리의 다른 글

[LNK2019] 확인할 수 없는 외부 참조입니다.  (1) 2015.03.13
GetLastError 1406  (0) 2014.05.19
RegisterTaskDefinition 80070534 error  (0) 2014.03.04
버그. 에러, 예외  (0) 2013.01.25
F5 실행 Ctrl F5 결과 값 차이 발생  (0) 2012.12.07

chapter01. 네트워크 프로그래밍과 소켓의 이해

1. 네트워크 프로그래밍에서 소켓이 담당하는 역할은 무엇인가? 그리고 소켓이라는 이름이 붙은 이유는 어디에 있는가?


2. 서버 프로그램에서는 소켓생성 이후에 listen 함수와 accept 함수를 차례대로 호출한다. 그렇다면 이들의 역할은 각각 무엇인지 비교해서 설명해보자.


3. 리눅스의 경우 파일 입출력 함수를 소켓 기반의 데이터 입출력에 사용할 수 있다. 반면 윈도우에서는 이것이 불가능하다. 그렇다면 리눅스에서는 가능하고, 윈도우에서는 불가능한 이유가 무엇인가?


4. 소켓을 생성한 다음에는 주소할당의 과정을 거친다. 그렇다면 주소할당이 필요한 이유는 무엇이며, 이를 목적으로 호출하는 함수는 또 무엇인가?


5. 리눅스의 파일 디스크립터와 윈도우의 핸들이 의미하는 바는 사실 같다. 그렇다면 이들이 의미하는 바가 무엇인지 소켓을 대상으로 설명해보자.


6. 저 수준 파일 입출력 함수와 ansi 표준에서 정의하는 파일 입출력 함수는 어떠한 차이가 있는가?


7. 본문에서 보인 예제 low_open.c와 low_read.c를 참조하여 파일 복사 프로그램을 작성하되, 저 수준 파일 입출력 함수를 기반으로, 그리고 ansi 표준 입출력 함수를 기반으로 각각 한번씩 작성해보자. 그리고 복사 프로그램의 사용방법은 여러분이 임의로 결정하기 바란다.

'and so on' 카테고리의 다른 글

라이브러리 사용 시 프로젝트 속성 설정  (0) 2015.04.15
[windbg] kb 명령어  (0) 2015.03.05
상속 vs 포함 (포함 예제)  (0) 2014.12.03
상속 vs 포함  (0) 2014.12.03
초성검색  (0) 2014.12.03

상속 vs 포함 (포함 예제)

///포함 관계라는 것은 클래스가 다른 클래스의 객체를 내부에 선언함으로써 포함된
///클래스의 기능을 공짜로 사용하는 것이다. 포함과 상속의 가장 큰 차이점은 다형성의
///발휘여부인데 상속은 클래스의 계층을 형성하여 다형성의 이점이 있지만 포함은
///코드를 한 번 재사용하는 정도의 기능 밖에 없다. 또한 상속은 protected 멤버를 자신의
///멤버처럼 자유롭게 액세스 하지만 포함은 그렇지 못하다.

 

using System;

 

class Human
{
    private string Name;
    private int Age;
    public Human(string aName, int aAge)
    {
        Name = aName;
        Age = aAge;
    }
    public void Intro()
    {
        Console.WriteLine("이름:" + Name);
        Console.WriteLine("나이:" + Age);
    }
}

class Student
{
    public Human H;             ///Human을 상속 받은것이 아니라 내부에 선언한것
                                ///즉, student 클래스 내부에 Human타입 객체 H를 포함
                                ///상속은 멤버를 바로 액세스 하지만, 포함한 경우는 객체의
                                ///이름을 통해야만 한다.
    protected int StNum;
    public Student(string aName, int aAge, int aStNum)
    {
        StNum = aStNum;
        H = new Human(aName, aAge);     ///Human의 Name과 Age변수를 호출
    }
    public void Intro()
    {
        H.Intro();                        ///Human의 메서드를 호출, 
        Console.WriteLine("학번:" + StNum);
    }
    public void Study()
    {
        Console.WriteLine("하늘 천 따지 검을 현 누를 황");
    }
}

class CSTest
{
    static void Main()
    {
        Student Kim;
        Kim = new Student("한석현", 29,0203446);
        Kim.Intro();
        Kim.Study();
    }
}


'and so on' 카테고리의 다른 글

[windbg] kb 명령어  (0) 2015.03.05
chapter01. 네트워크 프로그래밍과 소켓의 이해  (0) 2014.12.09
상속 vs 포함  (0) 2014.12.03
초성검색  (0) 2014.12.03
인덱싱  (0) 2014.12.03

상속 vs 포함

포함은 Has-a 관계다. A가 B를 가지고 있다면 (Has) 포함을 사용하라.

상속은 Is-a 관계다. A가 B라면(is) 상속을 사용하라

 

 

아래는 x,y 좌표를 저장하는 객체를 만든 모습입니다.

#include<iostream>
#include<cstring>
using namespace std;

class point{
private:
    int x,y;
public:
    point(int _x,int _y):x(_x),y(_y){};
    int getX(){
        return x;
    }
    int getY(){
        return y;
    }
};

int main(){
    point a(3,5);
    printf("%d %d",a.getX(),a.getY());
    return 0;
}

C++ 프로그래밍 경험이 있으신분들은 위 코드를 쉽게 이해하실거라 생각합니다.

아.. 생성자 부분에서 낯선부분이라고 생각하실 수 있는게..
point(int _x,int _y):x(_x),y(_y){}; // 이부분일까요?
point(int _x,int _y){
    x = _x;
    y = _y; 
} 와 완벽히 같은 내용입니다.

x = _x; // C style definition.
x(_x); // C++ style definition

위의 point 객체를 '포함' 하는 직사각형 객체 rectangle를 만들어봅시다.
단순히 point 객체를 변수로 가지는 직사각형 객체입니다.

#include<iostream>
#include<cstring>
using namespace std;

class point{
private:
    int x,y;
public:
    point(int _x,int _y):x(_x),y(_y){};
    int getX(){
        return x;
    }
    int getY(){
        return y;
    }
};

class rectangle{
private:
    point topLeft;
    point bottomRight; //point 객체 '포함'
public:
    rectangle(int a,int b,int c,int d):topLeft(a,b),bottomRight(c,d){};
    void print(){
        printf("Top Left : (%d , %d)\n",topLeft.getX(),topLeft.getY());
        printf("Bottom Right : (%d , %d)\n",bottomRight.getX(),bottomRight.getY());
    }
};

int main(){
    rectangle myRec(1,2,3,4);
    myRec.print();
    return 0;
}

rectangle 객체는 각 꼭지점의 위치를 point 객체를 이용하여 저장하고 있습니다.
객체가 다른 객체를 멤버변수로 사용하고 있는것을 '포함' 이라고 합니다.

 

아래는, 포함과 상속 모두를 사용한 예제입니다.
circle 객체는 point 객체를 '포함' 하여, 중심 좌표를 가지며
figure 객체를 상속하고 있습니다.
즉 circle 객체는 figure의 모든 public, protect 멤버에 대해서 접근이 가능합니다.
그중 protect는 상속받는 객체만이 public처럼 접근이 가능하고,
외부에서 protect변수는 private처럼 접근이 불가능합니다.
(circle이 figure을 상속받음)

#include<iostream>
#include<cstring>
using namespace std;

class point{
private:
    int x,y;
public:
    point(int _x,int _y):x(_x),y(_y){};
    int getX(){
        return x;
    }
    int getY(){
        return y;
    }
};

class figure{
private:
    char Name[20];
protected:
    char protect[50];
public:
    figure(char *_Name){
        strcpy_s(Name,_Name);
    }
    const char* getName() const{
        return Name;
    }
};

class circle : public figure // <-- 상속하는 부분
{
private:
    point center;
    int radius;
public:
    circle(int x,int y,int _radius)
        :center(x,y),figure("원"),radius(_radius){};
    void showData(){
        printf("%s 입니다.\n",getName()); //<-- figure 객체의 함수를 사용!
        printf("(x,y) : (%d,%d)\n",center.getX(),center.getY());
        printf("Radius : %d\n",radius);
        strcpy(protect,"protect는 마치 public처럼 접근가능!"); //Protect변수 접근가능
        printf("%s\n",protect);
    }
};

int main(){
    circle myCircle(5,5,5);
    myCircle.showData();
    return 0;
}


'and so on' 카테고리의 다른 글

chapter01. 네트워크 프로그래밍과 소켓의 이해  (0) 2014.12.09
상속 vs 포함 (포함 예제)  (0) 2014.12.03
초성검색  (0) 2014.12.03
인덱싱  (0) 2014.12.03
11/25 Build Your Own Webpage 1~6  (0) 2014.11.25

초성검색

Q) 초성으로 검색하는 기능을 추가하려고 합니다. 어떻게 구현하면 좋을까요?

     저는 트리를 이용한 검색을 설명했습니다.

RQ) 이 방법 보다는 인덱싱을 사용하면 좋을 것 같은데 어떻게 생각하나요? 재질문으로 인덱싱을 사용한 검색기능 구현법을 질문하셨습니다.

 

C++ 코드와 설명 출처: 데브피아

 

;- 유니코드 한글의 자모 분리법.
;
;
; 유니코드 완성형 한글 코드는 배치가 매우 잘되어 있어서 초성 중성 종성의 분리가 가능하다.
;
; wchar_t CompleteCode = L'가';
; 이렇게 완성형 코드가 있을 때
;
; wchar_t UniValue = CompleteCode - 0xAC00;
;
; 0xAC00은 한글 코드의 시작 값이다. 따라서 저 값을 빼면
; 우선적으로 우리가 원하는 한글 값만을 가지게 된다.
;
; 이제 저장한 UniValue로부터 종성을 분리한다.
; wchar_t Jong = UniValue % 28;
;
; 유니코드에서 사용가능한 초성은 19개, 중성은 21개, 종성은 28개이고
; 유니코드가 같는 값의 공식은
;
; 유니코드 완성형 값 = ( ( ( 초성 * 21 ) + 중성 ) * 28 ) + 종성 + 0xAC00;
;
; 이렇게 된다. 따라서 UniValue에서 28로 나눈 나머지는 종성이 된다.
;
; 이번에는 중성을 찾는다.
; wchar_t Jung = ( ( UniValue - Jong ) / 28 ) % 21;
; wchar_t Cho = ( ( UniValue - Jong ) / 28 ) / 21;
;
; 이렇게 하여 유니코드 완성형 값에서 초성, 중성, 종성의 값을 분리해낼 수 있다.
; 주의할 점은 저렇게 나오는 값은 인덱스 값이라는 점이다.
; 정확한 자모 값을 받기 위해서는 유니코드 한글 자모 코드표를 통해서
; 초성에는 초성 시작 값을 더해주고, 중성에는 중성 시작값을,
; 종성에는 종성의 시작값을 더해주어야 정확한 자모 값을 얻을 수 있다.
;
; 자, 이제 코드를 살펴보자...
;
; // unicode3.cpp
; #include <windows.h>
; #include <iostream>
; #include <locale>
;
; using namespace STD;
;
; INT main()
; {
;         wcout.imbue( locale("korean") );
;
;         wchar_t CompleteCode = L'개';
;         wchar_t UniValue = CompleteCode - 0xAC00;
;
;         wchar_t Jong = UniValue % 28;
;         wchar_t Jung = ( ( UniValue - Jong ) / 28 ) % 21;
;         wchar_t Cho = ( ( UniValue - Jong ) / 28 ) / 21;
;
;         cout << "초성 : " << Cho << "\t" << "중성 : " << Jung << "\t" << "종성 : " << Jong << endl;
; }
;
; 위와 같은 코드를 작성하여 살펴보면 '개'의 초성은 'ㄱ'이고, 중성은 'ㅐ', 종성은 없다.
; 따라서 'ㄱ'은 자모 코드 중 초성의 첫번째이므로 0의 값을 가지며,
; 'ㅐ'는 중성의 두번째이므로 1의 값을 가지고 종성은 없으므로 0의 값을 가지게 된다.
; 문제점은 종성의 0이다. 한글 코드는 초성이 없는 경우가 없고, 중성이 없는 경우는 없으나
; 종성이 없는 경우는 있다. 따라서 종성의 인덱스는 1부터 시작해야 한다.
; 저 위의 코드 중 L'개'를 L'객'으로 바꿔 살펴보면 종성 값이 1로 나오는 것을 확인할 수 있다.
;
; 유니코드의 자모값의 코드표에 대하여 알고 싶을 경우
;
 http://www.unicode.org/charts/PDF/U1100.pdf
;
; 그리고 한글 완성형 코드표에 대하여 알고 싶을 경우
;
 http://www.unicode.org/charts/PDF/UAC00.pdf
; 위의 링크에 가면 된다.


UniValue = Asc("객") - $AC00
Debug UniValue

 

jong = UniValue % 28
jung = ( ( UniValue - jong ) / 28 ) % 21
cho = ( ( UniValue - jong ) / 28 ) / 21

 

;각각의 인덱스 출력.
Debug cho
Debug jung
Debug jong

 

;실제 자모의 출력.
Debug Chr(cho+$1100)
Debug Chr(jung+$1161)
If jong   ;종성이 있으면 이하 처리.
  Debug Chr(jong+$11a7)
EndIf

 

 

실행 결과

 29
 0
 1
 1
 ㄱ
 ㅐ
 ㄱ

 

 

 

 

유니코드 전체 리스트
http://titus.uni-frankfurt.de/unicode/unitestx.htm

유니코드 한글 시작 부분 (AD00부터 시작)
http://titus.uni-frankfurt.de/unicode/unitestx.htm#UAD00

유니코드 한글 코드표(개인블로그)
http://sexy.pe.kr/tc/113

 

 


'and so on' 카테고리의 다른 글

상속 vs 포함 (포함 예제)  (0) 2014.12.03
상속 vs 포함  (0) 2014.12.03
인덱싱  (0) 2014.12.03
11/25 Build Your Own Webpage 1~6  (0) 2014.11.25
11/17 HTML Basics 1~8  (0) 2014.11.17

인덱싱

인덱스를 효율적으로 사용하면 MS SQL 서버의 쿼리 성능을 향상시킬 수 있지만, 이는 인덱스를 어떻게 구현하느냐에 달려있다. 그렇다면 데이터베이스 성능을 향상시킬 수 있는 인덱스 구현 방법은 어떤 것일까?

관계형 데이터베이스에서 인덱싱은 장단점이 있다. 즉 인덱스를 많이 사용하면 시스템에서 데이터를 빨리 추출할 수 있지만, 대신 새로운 데이터를 입력할 때 더 많은 시간이 소요된다. 이 글에서는 MS SQL 서버가 지원하는 다양한 인덱스 종류와 구현 방법에 대해 살펴 보고, 이를 통해 성능을 향상시키는 방법을 알아 본다.

인덱스의 정의
인덱스란 특정 레코드를 탐색할 때 데이터 전부를 탐색하지 않고도 데이터를 추출할 수 있는 데이터베이스 툴이다. 인덱스는 특정 데이터를 쉽게 추출할 수 있도록 데이터를 변경하는 것이 특징인데, 특히 열 형태로 구성되어 있어, 데이터베이스가 인덱스된 열의 값들을 추출하는데 용이하다.

인덱스의 종류
MS SQL 서버가 지원하는 인덱스는 클러스터 방식과 비클러스터 방식의 두 가지다. 먼저 클러스터 인덱스는 테이블에 저장된 데이터의 물리적 순서를 따른다. 테이블은 단일한 물리적 순서를 갖고 있기 때문에 테이블 당 하나의 클러스터 인덱스만 존재할 수 있다. 클러스터 인덱스는 데이터가 이미 물리적 순서를 갖고 있기 때문에 특정 범위의 데이터를 찾을 때 효율적이다.

비클러스터 인덱스는 물리적 스토리지에 영향을 주지 않고, 특정 데이터 행의 포인터들로 구성돼 있다. 만약 클러스터 인덱스가 존재하면, 비클러스터 인덱스의 포인터들은 클러스터 인덱스를 참조하는데, 이는 실제 데이터보다 크기가 작아, 더 신속하게 조사할 수 있다.

인덱스 생성 방법
일부 인덱스는 데이터베이스에 의해 자동으로 생성된다. 예를 들어 MS SQL 서버는 UNIQUE 제약조건에 따라 하나의 인덱스를 자동으로 생성하는데, 이는 중복 데이터가 입력되지 않도록 하는 기능을 담당한다. 이밖에도 CREATE INDEX 명령이나 인덱스 구축 마법사가 포함된 SQL 서버 엔터프라이즈 매니저를 통해 인덱스를 생성할 수 있다.

성능 향상
성능 향상에 관한한 인덱스는 일장일단이 있다. 예를 들어 SQL 서버는 테이블당 56개의 비클러스터 인덱스를 생성하는데, 인덱스가 메모리와 디스크 드라이브에 추가 공간을 차지한다는 사실을 감안하면 그리 바람직한 것은 아니다. 인덱스를 사용하면 데이터 추가시에도 성능 저하가 나타나는데, 이는 사용 가능한 가장 빠른 공간에 저장하는 것이 아니라 인덱스에 따라 데이터가 추가되기 때문에, 인덱스가 많아질수록 삽입이나 갱신 명령을 실행하는데 더 시간이 걸리는 것이다.

따라서 이처럼 MS SQL 서버에서 인덱스를 구축할 때는 아래와 같은 가이드라인을 참조하라. 

적절한 데이터 유형을 선택하라 : 데이터 유형 가운데에는 인덱스에 더 효율적인 유형이 있다. Int, bigint, smallint와 tinyint 등은 인덱스하기에 적합한 크기로 정의됐을 뿐만 아니라 비교 연산이 수월해 데이터 유형으로 안성맞춤이다. 반면 Char나 varchar와 같은 유형은 수학 연산이 쉽지 않고 비교에도 오랜 시간이 걸리므로 인덱스 유형으로는 비효율적이다.</li>

인덱스가 실제 사용되지는 확인하라 : 일부 클러스터 열을 포함한 질의를 수행할 경우에 데이터의 사용 방식에 주의해야 한다. 특정 명령이 데이터 열에 적용되는 경우 정렬의 이점을 상쇄하기 때문이다. 예를 들어 특정 데이터 값이 인덱스 되어 있는데 이를 비교하기 위해 문자열로 변환하면, 인덱스된 데이터 값은 이 질의에 사용되지 않는다.</li>

다중열 인덱스를 구축하는 경우 열의 순서에 유의하라 : 인덱스는 첫째 열을 기준으로 정렬된 이후에는, 추가된 열을 기준으로 정렬된다. 데이터 유일성이 떨어지는 열들은 인덱스에서 가장 앞에 나열되는데, 이는 인덱스 전체를 검토하면서 데이터 정렬이 이루어지도록 하기 위해서다.</li>

클러스터 인덱스의 열 수를 제한하라 : 클러스터 인덱스의 열 개수가 늘어날수록 클러스터 인덱스를 참조하는 비클러스터 인덱스에는 더 많은 데이터가 저장된다. 이는 인덱스를 포함한 테이블 크기를 증가시켜 인덱스 기반 검색 시간도 늘어나게 된다.</li>

업데이트가 잦은 열은 클러스터 인덱스를 피하라 : 비클러스터 인덱스는 클러스터 인덱스에 의존하기 때문에, 클러스터 인덱스 관련 열들이 자주 업데이트 되면 비클러스터 인덱스에 저장된 행 위치자들 역시 빈번하게 업데이트된다. 이와 같은 업데이트 과정 중에는 해당 열들이 ‘잠금 상태’가 되는데, 이런 상태는 모든 열에 대한 질의 성능을 떨어뜨린다.</li>

가능한 한 연산을 분할하라 : 삽입과 갱신, 판독이 자주 발생하는 테이블에서는 가능한한 테이블을 분리하는 것이 좋다. 삽입과 갱신은 인덱스 없이 가능하며, 데이터 판독에 최적화되어 무수한 인덱스를 갖는 테이블은 그 이후에도 복제해 생성할 수 있다.</li>

적절하게 인덱스를 재구축하라 : 비클러스터 인덱스는 클러스터 인덱스로의 포인터를 포함하기 때문에 클러스터 인덱스에 의존적이다. 클러스터 인덱스를 재생성하는 방법은 기존 인덱스를 삭제하고 CREATE INDEX 명령을 이용하거나, CREATE INDEX 명령에 DROP_EXISTING 문을 포함시키는 방법 등이 있다. 비클러스터 인덱스는 전자처럼 삭제와 생성 절차를 별도로 하면 여러번 재생성을 하지만 후자를 사용하면 단 한번으로 끝난다.</li>
채움 요소를 현명하게 사용하라 : 데이터는 일정한 크기의 연속된 페이지에 저장된다. 이미 꽉찬 데이터 페이지에 새로운 행들이 추가되면 시스템은 데이터의 반을 새로운 페이지로 옮기는 페이지 분리를 수행한다. 이는 시스템 부하를 증가시키고 데이터 파편화를 초래하는데, 이 때 채움 요소(fill factor)를 활용하면 인덱스 생성시 데이터 사이에 빈 공간을 유지해 데이터 삽입에 따른 페이지 분할 회수를 감소시킨다.

이 빈 공간은 인덱스를 생성할 때만 유지되며 데이터를 추가하거나 갱신할 때는 적용되지 않는다. 이 때문에 인덱스는 채움 요소를 계속 활용하기 위해 주기적으로 재생성할 필요가 있다. 또한 채움 요소로 남겨진 빈 공간은 데이터 판독시 디스크 읽기 부하를 높여 성능저하를 초래하므로, 판독 회수가 쓰기 회수보다 작은지를 비교해 기본 채움 요소 값 이외의 다른 값을 사용할지 결정해야 한다.</li>


이처럼 인덱스를 효율적으로 활용하면 MS SQL의 질의 성능을 향상시킬 수 있다. 그러나 효율적인 인덱스 사용은 인덱스 생성 과정에 따라 좌우되며, 특히 인덱스의 성능 측면에서 접근해야 개선을 기대할 수 있다. 지금까지 살펴 본 가이드라인을 활용하면 독자들의 데이터베이스 환경에 적합한 올바른 결정을 내릴 수 있을 것이다. @

[출처] 인덱싱|작성자 sang_it


'and so on' 카테고리의 다른 글

상속 vs 포함  (0) 2014.12.03
초성검색  (0) 2014.12.03
11/25 Build Your Own Webpage 1~6  (0) 2014.11.25
11/17 HTML Basics 1~8  (0) 2014.11.17
windows 톰캣 설치  (0) 2014.04.21